import rich_click as click
from novara.utils import logger
import os
import toml
from novara.request import request, JSONDecodeError
import json


def generate_dockerfile():
    try:
        with open("novara.toml", "r") as f:
            # exploit_config = toml.load(f)
            toml_raw = f.read()
    except (OSError, FileNotFoundError):
        raise click.ClickException("novara.toml either not there or unaccessable")

    logger.info("read toml file")

    logger.info("generating Dockerfile")
    r = request.post(
        f"api/build/dockerfile/toml/", data=json.dumps(toml_raw)
    )
    if not r.ok:
        raise click.ClickException(
            f"failed generating dockerfile with message: {r.text}"
        )
        exit()

    try:
        dockerfile_str = r.json()
    except JSONDecodeError:
        raise click.ClickException(
            f"failed to decode response as json: {r.text[:20] if len(r.text) > 20 else r.text}"
        )

    try:
        with open("Dockerfile", "w") as docker_file:
            docker_file.write(dockerfile_str)
    except OSError:
        raise click.ClickException("Dockerfile is unaccessable")
        exit()

    logger.info("generated Dockerfile")
    logger.info("run 'novara run local|remote' to start a container or remote container")


@click.command()
@click.option("--pip", default=None, help="add a new pip packages")
@click.option("--apt", default=None, help="add a new apt packages")
@click.option("--apk", default=None, help="add a new apk packages")
@click.option("--snap", default=None, help="add a new snap packages")
@click.option("--dnf", default=None, help="add a new dnf packages")
@click.option("--directory", "-d", default="./", help="path to exploit")
def generate(pip, apt, apk, snap, dnf, directory):
    """(re)generate the Dockerfile and add dependencies if necessary"""

    directory = os.path.join(directory, "novara.toml")

    if any([pip, apt, apk, snap, dnf]):
        logger.info("adding packages to novara.toml file")

        try:
            with open(directory, "r") as f:
                exploit_config = toml.load(f)
        except (OSError, FileNotFoundError):
            raise click.ClickException(f"{directory} either not there or unaccessable")
            exit()

        docker_config = exploit_config.get("docker", None)
        if docker_config is None:
            raise click.ClickException("docker key not found in toml")
            exit()

        dependencies = docker_config.get("dependencies", None)
        if dependencies is None:
            raise click.ClickException("docker.dependencies key not found in toml")
            exit()

        pip_packages = dependencies.get("pip", None)
        apt_packages = dependencies.get("apt", None)
        apk_packages = dependencies.get("apk", None)
        dnf_packages = dependencies.get("dnf", None)
        snap_packages = dependencies.get("snap", None)

        if pip is not None:
            dependencies.update(
                {"pip": [pip] if pip_packages is None else pip_packages + [pip]}
            )

        if apt is not None:
            dependencies.update(
                {"apt": [apt] if apt_packages is None else apt_packages + [apt]}
            )

        if apk is not None:
            dependencies.update(
                {"apk": [apk] if apk_packages is None else apk_packages + [apk]}
            )

        if dnf is not None:
            dependencies.update(
                {"dnf": [dnf] if dnf_packages is None else dnf_packages + [dnf]}
            )

        if snap is not None:
            dependencies.update(
                {"snap": [snap] if snap_packages is None else snap_packages + [snap]}
            )

        try:
            with open(directory, "w") as f:
                f.write(
                    "# novara configuration file autogenerated by the novara cli, only edit if you know what you are doing\n\n"
                )
                toml.dump(exploit_config, f)
        except (OSError, FileNotFoundError):
            raise click.ClickException(f"{directory} either not there or unaccessable")
            exit()

        logger.info("updated novara.toml file")

    generate_dockerfile()
