#!/usr/bin/env python
# coding: utf-8
# /*##########################################################################
#
# Copyright (c) 2017 European Synchrotron Radiation Facility
#
# 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.
#
# ###########################################################################*/
"""This module describe tomwer applications which are available  through
the silx launcher.

Your environment should provide a command `tomwer`. You can reach help with
`tomwer --help`, and check the version with `tomwer --version`.
"""

__authors__ = ["V. Valls", "P. Knobel", "H. Payno"]
__license__ = "MIT"
__date__ = "10/11/2020"


import sys
from collections import namedtuple
import tomwer.version
from tomwer.utils import Launcher as _Launcher
from tomwer.core.utils.deprecation import deprecated_warning

DeprecationWarning = namedtuple(
    "DeprecationWarning", ["since", "reason", "replacement"]
)


class Launcher(_Launcher):
    """
    Manage launch of module.

    Provides an API to describe available commands and feature to display help
    and execute the commands.
    """

    def __init__(
        self, prog=None, usage=None, description=None, epilog=None, version=None
    ):
        super().__init__(
            prog=prog,
            usage=usage,
            description=description,
            epilog=epilog,
            version=version,
        )
        self._deprecations = {}
        "deprecations with prog names as key and deprecation info as values"

    def add_command(
        self,
        name=None,
        module_name=None,
        description=None,
        command=None,
        deprecated=False,
        deprecated_since_version=None,
        deprecated_reason=None,
        deprecated_replacement=None,
    ):
        super().add_command(
            name=name, module_name=module_name, description=description, command=command
        )
        if deprecated:
            self._deprecations[name] = DeprecationWarning(
                since=deprecated_since_version,
                reason=deprecated_reason,
                replacement=deprecated_replacement,
            )

    def execute(self, argv=None):
        if argv is None:
            argv = sys.argv

        if len(argv) <= 1:
            self.print_help()
            return 0

        command_name = argv[1]

        if command_name in self._deprecations:
            deprecation_info = self._deprecations[command_name]
            deprecated_warning(
                type_="application",
                name=command_name,
                reason=deprecation_info.reason,
                replacement=deprecation_info.replacement,
                since_version=deprecation_info.since,
            )
        super().execute(argv=argv)


def main():
    """Main function of the launcher

    This function is referenced in the setup.py file, to create a
    launcher script generated by setuptools.

    :rtype: int
    :returns: The execution status
    """
    _version = tomwer.version.version
    launcher = Launcher(prog="tomwer", version=_version)
    launcher.add_command(
        "axis",
        module_name="tomwer.app.axis",
        description="Compute center of rotation of a scan or "
        "between two projections",
    )
    launcher.add_command(
        "canvas", module_name="tomwer.app.canvas", description="open the orange-canvas"
    )
    launcher.add_command(
        "dark-ref",
        module_name="tomwer.app.reducedarkflat",
        description="Compute mean / median darks and flat fields",
        deprecated=True,
        deprecated_reason="improve name",
        deprecated_replacement="reduce-dark-flat",
        deprecated_since_version=1.2,
    )
    launcher.add_command(
        "dark-ref-patch",
        module_name="tomwer.app.patchrawdarkflat",
        description="patch raw dark and / or flat to an NXTomo entry",
        deprecated=True,
        deprecated_reason="improve name",
        deprecated_replacement="patch-raw-dark-flat",
        deprecated_since_version=1.2,
    )
    launcher.add_command(
        "diff-frame",
        module_name="tomwer.app.diffframe",
        description="Tool to compare any frame from the acquisition",
    )
    launcher.add_command(
        "image-key-editor",
        module_name="tomwer.app.imagekeyeditor",
        description="Tool to modify in place frames image key parameter.",
    )
    launcher.add_command(
        "image-key-upgrader",
        module_name="tomwer.app.imagekeyupgrader",
        description="Tool to upgrade in place frames image key parameter.",
    )
    launcher.add_command(
        "norm-intensity",
        module_name="tomwer.app.intensitynormalization",
        description="Tool to compute intensity normalization.",
    )
    launcher.add_command(
        "multi-cor",
        module_name="tomwer.app.multicor",
        description="Compute a slice with different values of cor",
    )
    launcher.add_command(
        "multi-pag",
        module_name="tomwer.app.multipag",
        description="compute a slice with different values of delta / beta values",
    )
    launcher.add_command(
        "nabu",
        module_name="tomwer.app.nabuapp",
        description="Use nabu to reconstruct a given scan",
    )
    launcher.add_command(
        "nxtomo-editor",
        module_name="tomwer.app.nxtomoeditor",
        description="Use to edit an NXtomo",
    )
    launcher.add_command(
        "ows-to-script",
        module_name="tomwer.app.ows_to_script",
        description="Convert a .ows file to python script",
    )
    launcher.add_command(
        "patch-raw-dark-flat",
        module_name="tomwer.app.patchrawdarkflat",
        description="patch raw dark and / or flat to an NXTomo entry",
    )
    launcher.add_command(
        "reduce-dark-flat",
        module_name="tomwer.app.reducedarkflat",
        description="Compute reduce darks / flats (mean / median of raw darks and flats)",
    )
    launcher.add_command(
        "rsync",
        module_name="tomwer.app.rsync",
        description="Tool for synchronization between "
        "acquisition contained in a folder and "
        "a target folder",
    )
    launcher.add_command(
        "sample-moved",
        module_name="tomwer.app.samplemoved",
        description="Interface to check if a sample have " "moved during acquisition ",
    )
    launcher.add_command(
        "slice-stack",
        module_name="tomwer.app.slicestack",
        description="Display each reconstruction contained "
        "in the ROOT_DIR or sub-folders",
    )
    launcher.add_command(
        "sinogram-viewer",
        module_name="tomwer.app.sinogramviewer",
        description="Allows to compute on the fly sinogram " "and display them",
    )
    launcher.add_command(
        "scan-viewer",
        module_name="tomwer.app.scanviewer",
        description="Scan viewer / browser",
    )
    launcher.add_command(
        "stop-data-listener",
        module_name="tomwer.app.stopdatalistener",
        description="Send SIGTERM or SIGKILL signal to the process occupying"
        "rpc-server port",
    )
    launcher.add_command(
        "test", module_name="tomwer.app.test_", description="Launch tomwer unittest"
    )
    launcher.add_command(
        "z-stitching",
        module_name="tomwer.app.zstitching",
        description="Launch z-stitcher interface",
    )
    status = launcher.execute(sys.argv)
    return status


if __name__ == "__main__":
    # executed when using python -m PROJECT_NAME
    status = main()
    sys.exit(status)
