import datetime
import logging
import os
import sqlite3
import subprocess

import pandas as pd
import yaml
from slugify import slugify

log = logging.getLogger(__name__)

yesterday = (datetime.datetime.now() - datetime.timedelta(days=1)).strftime('%Y-%m-%d')

with open("scripts/tools/build_fail_definitions.yaml", "r") as fail_defs:
    try:
        error_catalog = yaml.safe_load(fail_defs)
    except Exception:
        log.exception("Could not load fail definition file.")


def pass_fail_rate(workflow):
    log.info("Checking recent pass/fail rate of workflow '%s'", workflow)
    workflow_fail_rate_output_path = f"workflow_pass_rate/{slugify(workflow)}"
    if not os.path.exists(workflow_fail_rate_output_path):
        os.makedirs(workflow_fail_rate_output_path)
        subprocess.run(
            f"gh run list -R project-chip/connectedhomeip -b master -w '{workflow}' -L 500 --created {yesterday} --json conclusion > {workflow_fail_rate_output_path}/run_list.json", shell=True)
    else:
        log.info("This workflow has already been processed.")


def process_fail(id, pr, start_time, workflow):
    log.info("Processing failure in PR '%s', workflow '%s' that started at '%s'", pr, workflow, start_time)

    log.info("Building output file structure.")
    output_path = f"recent_fails_logs/{slugify(pr)}/{slugify(workflow)}/{slugify(start_time)}"
    os.makedirs(output_path)

    log.info("Gathering raw fail logs.")
    subprocess.run(f"gh run view -R project-chip/connectedhomeip {id} --log-failed > {output_path}/fail_log.txt", shell=True)

    # Eventually turn this into a catalog of error messages per workflow
    log.info("Collecting info on likely cause of failure.")
    root_cause = "Unknown cause"
    with open(f"{output_path}/fail_log.txt") as fail_log_file:
        fail_log = fail_log_file.read()
        workflow_category = workflow.split(" - ")[0]
        if workflow_category in error_catalog:
            for error_message in error_catalog[workflow_category]:
                if error_message in fail_log:
                    root_cause = error_catalog[workflow_category][error_message]["short"]
                    break

    return [pr, workflow, root_cause]


def main():
    log.info("Gathering recent fails information into fail_run_list.json.")
    subprocess.run(
        f"gh run list -R project-chip/connectedhomeip -b master -s failure -L 500 --created {yesterday} --json databaseId,displayTitle,startedAt,workflowName > fail_run_list.json", shell=True)

    log.info("Reading fail_run_list.json into a DataFrame.")
    df = pd.read_json("fail_run_list.json")

    log.info("Listing recent fails from '%s'", yesterday)
    df.columns = ["ID", "Pull Request", "Start Time", "Workflow"]
    print(f"Recent Fails From {yesterday}:")
    print(df.to_string(columns=["Pull Request", "Workflow"], index=False))
    print()
    df.to_csv("recent_fails.csv", index=False)

    log.info("Listing frequency of recent fails by workflow.")
    frequency = df["Workflow"].value_counts(normalize=True).mul(100).round().astype(
        str).reset_index(name="Percentage")  # Reformat this from "50.0" to "50%"
    print("Share of Recent Fails by Workflow:")
    print(frequency.to_string(index=False))
    print()
    frequency.to_csv("recent_workflow_fails_frequency.csv")

    log.info("Gathering recent runs information into all_run_list.json.")
    subprocess.run(
        f"gh run list -R project-chip/connectedhomeip -b master -L 5000 --created {yesterday} --json workflowName > all_run_list.json", shell=True)

    log.info("Reading all_run_list.json into a DataFrame.")
    all_df = pd.read_json("all_run_list.json")

    log.info("Gathering pass/fail rate info.")
    all_df.columns = ["Workflow"]
    all_df.apply(lambda row: pass_fail_rate(row["Workflow"]), axis=1)

    log.info("Conducting fail information parsing.")
    root_causes = df.apply(lambda row: process_fail(row["ID"], row["Pull Request"],
                           row["Start Time"], row["Workflow"]), axis=1, result_type="expand")
    root_causes.columns = ["Pull Request", "Workflow", "Cause of Failure"]
    print("Likely Root Cause of Recent Fails:")
    print(root_causes.to_string(index=False))
    print()
    root_causes.to_csv("failure_cause_summary.csv")

    log.info("Listing percent pass rate of recent fails by workflow.")
    pass_rate = {}
    for workflow in next(os.walk("workflow_pass_rate"))[1]:
        try:
            info = pd.read_json(f"workflow_pass_rate/{workflow}/run_list.json")
            info = info[info["conclusion"].str.len() > 0]
        except Exception:
            log.exception("Recent runs info for '%s' was not collected.", workflow)
        try:
            pass_rate[workflow] = [info.value_counts(normalize=True).mul(100).round()["success"]]
        except Exception:
            pass_rate[workflow] = [0.0]
    pass_rate = pd.DataFrame.from_dict(pass_rate, 'index', columns=["Pass Rate"]).sort_values("Pass Rate")
    print("Recent Pass Rate of Each Workflow:")
    pass_rate.to_markdown("docs/daily_pass_percentage.md")
    pass_rate_sql = sqlite3.connect("workflow_pass_rate.sqlite3")
    pass_rate.to_sql("workflow_pass_rate", pass_rate_sql, if_exists="replace")
    print(pass_rate.to_string())
    pass_rate.to_csv("workflow_pass_rate.csv")


if __name__ == "__main__":
    main()
