#    JointBox CLI
#    Copyright (C) 2021 Dmitry Berezovsky
#    The MIT License (MIT)
#
#    Permission is hereby granted, free of charge, to any person obtaining
#    a copy of this software and associated documentation files
#    (the "Software"), to deal in the Software without restriction,
#    including without limitation the rights to use, copy, modify, merge,
#    publish, distribute, sublicense, and/or sell copies of the Software,
#    and to permit persons to whom the Software is furnished to do so,
#    subject to the following conditions:
#
#    The above copyright notice and this permission notice shall be
#    included in all copies or substantial portions of the Software.
#
#    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
#    EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
#    MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
#    IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
#    CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
#    TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
#    SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

import copy
import datetime
import logging

import yaml

import strome.const
from strome.core import (
    process_strome_config,
    load_context_path,
    preload_modules,
    setup_pipeline,
    Pipeline,
    DEFAULT_PROCESSORS_CONFIG,
)
from strome.utils import yaml_file_to_dict

from jointbox_cli.pipeline import JointboxRuntime

LOGGER = logging.getLogger("core")

PIPELINE_DEF = (
    "secrets",
    "esphome-repos",
    "esphome-packages",
)

DEFAULT_JOINTBOX_CONF = copy.deepcopy(DEFAULT_PROCESSORS_CONFIG)
DEFAULT_JOINTBOX_CONF[strome.const.CONF_PRELOAD] = (
    "jointbox_cli.esphome_ext.repositories.RepositoriesProcessingPipeline",
    "jointbox_cli.esphome_ext.packages.PackagesProcessingPipeline",
    "jointbox_cli.secrets.SecretsPipeline",
)
DEFAULT_JOINTBOX_CONF[strome.const.CONF_PIPELINE] = PIPELINE_DEF

GENERATED_YAML_PREAMBLE = """
# DO NOT EDIT
# This file was generated by JointBox CLI on {date}

"""


def read_config_yaml(config_path: str):
    config_dict = load_yaml_config_file(config_path)
    LOGGER.info("Loaded jointbox config {}".format(config_path))
    flow_runtime = JointboxRuntime(config_path, config_dict)

    if flow_runtime.root_config_element not in config_dict:
        config_dict[flow_runtime.root_config_element] = copy.deepcopy(DEFAULT_JOINTBOX_CONF)
    process_strome_config(config_dict, flow_runtime)

    flow_runtime.init()
    return flow_runtime


def write_generated_yaml(flow_runtime: JointboxRuntime, file_path: str):
    data = copy.copy(flow_runtime.config)
    del data[flow_runtime.root_config_element]
    with open(file_path, "w") as f:
        f.write(GENERATED_YAML_PREAMBLE.format(date=datetime.datetime.now().isoformat()))
        return yaml.dump(data, f)


def load_yaml_config_file(config_path: str):
    return yaml_file_to_dict(config_path)


def prepare_pipeline(flow_runtime: JointboxRuntime) -> Pipeline:
    # Load libs and setup context path
    load_context_path(flow_runtime)
    # Setup pipeline
    preload_modules(flow_runtime)
    # Initialize secrets manager
    pipeline = setup_pipeline(flow_runtime.flow_config.get(strome.const.CONF_PIPELINE, []), flow_runtime)
    return pipeline
