#!/usr/bin/env python
"""
Defines the setup script. This installs UCVM and downloads all the requested models. Models
can be added or deleted after the fact with the ucvm_model_manager utility. This auto-downloads new
models and can remove existing ones.

Copyright 2017 Southern California Earthquake Center

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
"""
# Python Imports
import os
import sys
from subprocess import Popen

# UCVM Imports
from ucvm.src.framework.ucvm import UCVM
from ucvm.src.model import get_list_of_installable_internet_models, get_list_of_installed_models, \
                           install_internet_ucvm_model, UCVM_MODELS_DIRECTORY, UCVM_LIBRARIES_DIRECTORY


def usage() -> None:
    """
    Displays the help text associated with this utility.

    Returns:
        Nothing
    """
    UCVM.print_with_replacements(
        "\n"
        "ucvm_model_manager - UCVM Version [version]\n"
        "\n"
        "Add and list models from UCVM with this program. Models are downloaded through the\n"
        "web. This utility can also be used to list the models that you have installed with UCVM.\n"
        "\n"
        "-l, --list:            Lists all models available and states which ones are installed.\n"
        "-a, --add model:       Downloads and installs 'model' and adds it to UCVM.\n"
    )


def main() -> int:
    """
    The main UCVM model manager function.
    Returns:
        0 if successful. Raises an error code otherwise, if not.
    """
    try:
        options = UCVM.parse_options([
            {"short": "l", "long": "list", "value": False, "required": False},
            {"short": "a", "long": "add", "value": True, "required": False}
        ], usage)
    except ValueError as v_err:
        print("[ERROR]: " + str(v_err) + "\n")
        sys.exit(-1)

    if options["add"] is not None:
        model_list = get_list_of_installable_internet_models()

        found = False

        for _, models in model_list.items():
            for item in models:
                if item["id"] == options["add"]:
                    found = item
                elif item["file"].split(".")[0] == options["add"]:
                    found = item
                    found["id"] = options["add"].strip()

        if not found:
            print("Model " + options["add"] + " was not found in the list of installable models.")
            return -1

        # We have found the model. We need to install it!
        info = install_internet_ucvm_model(found["id"], found["name"])

        # Now run the tests, through the command line so that the library paths are correct!
        environment_variable = "LD_LIBRARY_PATH"
        if sys.platform == "darwin":
            environment_variable = "DYLD_LIBRARY_PATH"

        paths = []
        if environment_variable in os.environ:
            paths = str(os.environ[environment_variable]).split(":")

        # This is Cythonized code.
        paths.append(os.path.join(UCVM_MODELS_DIRECTORY, found["id"], "lib"))
        paths.append(os.path.join(UCVM_LIBRARIES_DIRECTORY, "euclid3", "lib"))

        os.environ[environment_variable] = ":".join(paths)

        p = Popen([sys.executable] + [os.path.join(os.path.dirname(os.path.abspath(__file__)), "ucvm_run_tests"),
                                      "-m", info["id"]], env=os.environ)
        p.wait()
    elif options["list"] is not None:
        model_list = get_list_of_installable_internet_models()
        installed_list = get_list_of_installed_models()

        installed_list_c = {
            "velocity": [list(dict(x).keys())[0] for x in dict(installed_list)["velocity"]],
            "elevation": [list(dict(x).keys())[0] for x in dict(installed_list)["elevation"]],
            "vs30": [list(dict(x).keys())[0] for x in dict(installed_list)["vs30"]],
            "operator": [list(dict(x).keys())[0] for x in dict(installed_list)["operator"]]
        }

        print("\nThe following are models that you have not installed but are available for\n"
              "download from SCEC:\n")

        for key, models in model_list.items():
            temp_str = ""
            for item in models:
                if item["id"] in installed_list_c[key]:
                    continue
                temp_str += "Name: " + item["name"] + "\n"
                temp_str += item["description"] + "\n"
                temp_str += "To install this model: ucvm_model_manager -a " + item["id"] + "\n\n"
            if temp_str != "":
                print(str(key).capitalize() + ":")
                print(temp_str, end="")
    return 0

if __name__ == "__main__":
    main()
