import configparser
import argparse
from bs4 import BeautifulSoup
import json
from elasticsearch import Elasticsearch
import os
import datetime


PARSER = argparse.ArgumentParser()
PARSER.add_argument("-j", "--CI_JOB_ID", default='1')
PARSER.add_argument("-n", "--COMPONENT_NAME")
PARSER.add_argument("-p", "--PRODUCT_NAME")
PARSER.add_argument("-i", "--INDEX_NAME")
PARSER.add_argument("-b", "--BRANCH_NAME", default='dev')
ARGS = PARSER.parse_args()

config = configparser.ConfigParser()
config.read("config.ini")

elk_host = config.get("elk_properties", "host")
elk_port = config.get("elk_properties", "port")
elk_pwd = config.get("elk_properties", "password")
elastic_client = Elasticsearch(hosts=[{'host': elk_host, 'port': elk_port}], http_auth=('elastic', elk_pwd))

m_filePath = os.getcwd()

component_name = str(ARGS.COMPONENT_NAME)
group_name = str(ARGS.PRODUCT_NAME)
elk_index = str(ARGS.INDEX_NAME)


def myconverter(o):
    if isinstance(o, datetime.datetime):
        return o.__str__()


# Gets Jest test data
def testcount():
    with open(m_filePath+ os.sep + "test-report.html", "r",encoding="UTF-8") as f:
        content = f.read()
        soup = BeautifulSoup(content, 'html.parser')
        data = soup.find("script").string
        data1 = data[21:]
        data2 = json.loads(data1)
        data3 = json.loads(data2)
        passedtestcount = data3["numPassedTests"]
        failuretestcount = data3["numFailedTests"]
        pendingtestcount = data3["numPendingTests"]
        totaltestcount = passedtestcount + failuretestcount + pendingtestcount
        passedsuitcount = data3["numPassedTestSuites"]
        failuresuitcount = data3["numFailedTestSuites"]
        pendingsuitcount = data3["numPendingTestSuites"]
        totalsuitcount = passedsuitcount + failuresuitcount + pendingsuitcount
    dict = [{"name":"Tests","result":[{'Total': totaltestcount, 'Passed': passedtestcount, 'Failed': failuretestcount, 'Pending': pendingtestcount}]},
            {"name":"Suites","result":[{'Total': totalsuitcount, 'Passed': passedsuitcount, 'Failed': failuresuitcount, 'Pending': pendingsuitcount}]}]

    return dict


# Formats the dict returned by testcount into the dict required for elasticsearch index
def get_elk_testcount_dict():
    test_data_dict = testcount()
    fields_dict_array = [{"tests.passed": "Passed", "tests.failed": "Failed", "tests.pending": "Pending", "tests.total": "Total"}, {"suites.passed": "Passed", "suites.failed": "Failed", "suites.pending": "Pending", "suites.total": "Total"}]
    final_test_dict = {}
    i = 0
    for element in fields_dict_array:
        for field, d in element.items():
            final_test_dict[field] = test_data_dict[i]["result"][0][d]
        i = i + 1
    return final_test_dict


# Creates the dict required to insert the test data in elasticsearch with additional information
def get_elk_test_data(elk_testdata_dict, build, product, module, test_type="jest"):
    elk_testdata_dict["build.no"] = build
    elk_testdata_dict["module"] = module
    elk_testdata_dict["product"] = product
    elk_testdata_dict["test.type"] = test_type
    elk_testdata_dict["timestamp"] = datetime.datetime.utcnow()
    return elk_testdata_dict


# Insert the test data in elk
def jsonfile():
    elk_doctype = elk_index + "_log"
    build = str(ARGS.CI_JOB_ID)
    elk_testcount_dict = get_elk_testcount_dict()
    elk_test_data = get_elk_test_data(elk_testdata_dict=elk_testcount_dict, build=build, product=group_name, module=component_name)
    with open("jest.json", "w") as outfile:
        json.dump(elk_test_data, outfile, indent=4, default=myconverter)
        elastic_client.index(index=elk_index, doc_type=elk_doctype,
                             body=elk_test_data, request_timeout=50)
        elastic_client.indices.refresh(index=elk_index, request_timeout=50)
    return 'done'


# Insert elk data only for master branch
main_branch_name = "master"
if str(ARGS.BRANCH_NAME) == main_branch_name:
    jsonfile()
else:
    print("Not a main branch")

