import typer
import json
import os
import requests
import jsonschema
import tempfile
import shutil
from pathlib import Path
from src.providers.json.json_render import save_json, save_json_diff
from src.providers.plantuml.pu_render import save_plant_uml, save_plant_uml_diff
from src.utils.path_manager_singleton import PathManagerSingleton

# from src.utils.functions import verify_config_options
from src.utils.config_manager_singleton import ConfigManagerSingleton

from src.views.view_manager import render_views, render_diff_views

from src.core.bt_graph import BTGraph

from src.git_integration.fetch_git import fetch_git_repo

from astroid.manager import AstroidManager

import astroid

astroid.MANAGER = None

app = typer.Typer(add_completion=True)


@app.command()
def render(config_path: str = "archlens.json"):
    config = read_config_file(config_path)

    mt_path_manager = PathManagerSingleton()
    mt_path_manager.setup(config)

    am = _create_astroid()
    g = BTGraph(am)
    g.build_graph(config)

    render_views(g, config, save_plant_uml)


@app.command()
def render_json(config_path: str = "archlens.json"):
    config = read_config_file(config_path)

    mt_path_manager = PathManagerSingleton()
    mt_path_manager.setup(config)

    am = _create_astroid()
    g = BTGraph(am)
    g.build_graph(config)

    render_views(g, config, save_json)


def _create_astroid():
    am = AstroidManager()
    am.brain["astroid_cache"] = {}
    return am


@app.command()
def render_diff(config_path: str = "archlens.json"):
    with tempfile.TemporaryDirectory() as tmp_dir:
        print("Created temporary directory:", tmp_dir)
        config = read_config_file(config_path)

        fetch_git_repo(tmp_dir, config["github"]["url"], config["github"]["branch"])

        shutil.copyfile(config_path, os.path.join(tmp_dir, "archlens.json"))

        config_git = read_config_file(os.path.join(tmp_dir, "archlens.json"))

        path_manager = PathManagerSingleton()
        path_manager.setup(config, config_git)

        local_am = _create_astroid()
        local_graph = BTGraph(local_am)
        local_graph.build_graph(config)
        # verify_config_options(config, g)

        remote_am = _create_astroid()
        remote_graph = BTGraph(remote_am)
        remote_graph.build_graph(config_git)
        # verify_config_options(config_git, g_git)

        render_diff_views(local_graph, remote_graph, config, save_plant_uml_diff)


@app.command()
def render_diff_json(config_path: str = "archlens.json"):
    with tempfile.TemporaryDirectory() as tmp_dir:
        print("Created temporary directory:", tmp_dir)
        config = read_config_file(config_path)

        fetch_git_repo(tmp_dir, config["github"]["url"], config["github"]["branch"])

        shutil.copyfile(config_path, os.path.join(tmp_dir, "archlens.json"))

        config_git = read_config_file(os.path.join(tmp_dir, "archlens.json"))

        path_manager = PathManagerSingleton()
        path_manager.setup(config, config_git)

        local_am = _create_astroid()
        local_graph = BTGraph(local_am)
        local_graph.build_graph(config)
        # verify_config_options(config, g)

        remote_am = _create_astroid()
        remote_graph = BTGraph(remote_am)
        remote_graph.build_graph(config_git)
        # verify_config_options(config_git, g_git)

        render_diff_views(local_graph, remote_graph, config, save_json_diff)


@app.command()
def init(config_path="./archlens.json"):
    os.makedirs(os.path.dirname(config_path), exist_ok=True)
    template_path = os.path.join(os.path.dirname(__file__), "config.template.json")
    schema = None
    with open(template_path, "r") as f:
        schema = json.load(f)

    schema["name"] = os.path.basename(os.getcwd())
    with open(config_path, "w") as outfile:
        json.dump(schema, outfile, indent=4)


@app.command()
def create_action():
    action_url = "https://raw.githubusercontent.com/archlens/ArchLens/master/.github/workflows/render-diff-on-pr.yml"
    action_path = Path(".github/workflows/render-diff-on-pr.yml")
    typer.secho(f"Creating the action at {action_path}", fg="green")
    action_path.parent.mkdir(parents=True, exist_ok=True)
    action = requests.get(action_url).text

    with open(action_path, "w") as f:
        f.write(action)


def read_config_file(config_path):
    config = None
    with open(config_path, "r") as f:
        config = json.load(f)

    config_schema = None
    schema_path = os.path.join(os.path.dirname(__file__), "config.schema.json")
    with open(schema_path) as fp:
        config_schema = json.load(fp)

    if not os.getenv("MT_DEBUG"):
        jsonschema.validate(instance=config, schema=config_schema)

    config["_config_path"] = os.path.dirname(os.path.abspath(config_path))

    config["saveLocation"] = os.path.normpath(
        os.path.join(config["_config_path"], config["saveLocation"])
    )

    config_manager = ConfigManagerSingleton()
    config_manager.setup(config)

    return config


def main():
    app()


if __name__ == "__main__":
    main()
