#!/usr/bin/env python
"""This module describe nxtomomill applications which are available  through
the silx launcher.

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

import logging
import sys
from collections import namedtuple

from silx.utils.launcher import Launcher as _Launcher

import nxtomomill.version
from nxtomomill.utils.io import deprecated_warning

logging.basicConfig()


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 print_help(self):
        """Print the help to stdout."""
        usage = self.usage
        if usage is None:
            usage = "usage: {0.prog} [--version|--help] <command> [<args>]"
        description = self.description
        epilog = self.epilog
        if epilog is None:
            epilog = "See '{0.prog} help <command>' to read about a specific subcommand"

        print(usage.format(self))
        print("")
        if description is not None:
            print(description)
            print("")
        print("The {0.prog} commands are:".format(self))
        commands = sorted(self._commands.keys())
        for command in commands:
            command = self._commands[command]
            print("   {:15} {:s}".format(command.name, command.description))
        print("")
        print(epilog.format(self))


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

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

    :returns: The execution status
    """
    _version = nxtomomill.version.version
    launcher = Launcher(prog="nxtomomill", version=_version)
    launcher.add_command(
        "nx-copy",
        module_name="nxtomomill.app.nxcopy",
        description="Copy one or several NXtomo to another location",
    )
    launcher.add_command(
        "dxfile2nx",
        module_name="nxtomomill.app.dxfile2nx",
        description="Convert dx file to NXTomo",
    )
    launcher.add_command(
        "patch-nx",
        module_name="nxtomomill.app.patch_nx",
        description="allow to patch an NXTomo entry",
    )
    launcher.add_command(
        "tomoedf2nx",
        module_name="nxtomomill.app.edf2nx",
        description="convert spec-edf acquisition to nexus - hdf5",
        deprecated=True,
        deprecated_reason="remove `tomo` repetition. The shorter the better",
        deprecated_replacement="edf2nx",
        deprecated_since_version=0.5,
    )
    launcher.add_command(
        "edf2nx",
        module_name="nxtomomill.app.edf2nx",
        description="convert spec-edf acquisition to nexus - hdf5"
        "format to nx compliant file format",
    )
    launcher.add_command(
        "edf2nx-check",
        module_name="nxtomomill.app.edf2nx_check",
        description="check a conversion from EDF to Nxtomo and optionally remove EDF files",
    )
    launcher.add_command(
        "edf-quick-start",
        module_name="nxtomomill.app.edfconfig",
        description="create a configuration file to convert from spec-edf to NXtomo",
        deprecated_replacement="edf-config",
        deprecated_since_version=0.13,
    )
    launcher.add_command(
        "edf-config",
        module_name="nxtomomill.app.edfconfig",
        description="create a configuration file to convert from spec-edf to NXtomo",
    )
    launcher.add_command(
        "fluo-config",
        module_name="nxtomomill.app.fluoconfig",
        description="create a configuration file to convert from fluo-tomo to NXtomo",
    )
    launcher.add_command(
        "fluo2nx",
        module_name="nxtomomill.app.fluo2nx",
        description="Converts from XRFCT data to NXtomo",
    )
    launcher.add_command(
        "blissfluo-config",
        module_name="nxtomomill.app.blissfluoconfig",
        description="create a configuration file to convert from blissfluo-tomo to NXtomo",
    )
    launcher.add_command(
        "blissfluo2nx",
        module_name="nxtomomill.app.blissfluo2nx",
        description="Converts from (Bliss) XRFCT data to NXtomo",
    )
    launcher.add_command(
        "tomoh52nx",
        module_name="nxtomomill.app.h52nx",
        description="convert bliss hdf5 to nexus hdf5",
        deprecated=True,
        deprecated_reason="remove `tomo` repetition. The shorter the better",
        deprecated_replacement="h52nx",
        deprecated_since_version=0.5,
    )
    launcher.add_command(
        "h52nx",
        module_name="nxtomomill.app.h52nx",
        description="convert bliss hdf5 to nexus hdf5",
    )
    launcher.add_command(
        "z-concatenate-scans",
        module_name="nxtomomill.app.z_concatenate_scans",
        description="Build a concatenation nexus file from a z-series",
    )
    launcher.add_command(
        "zstages2nxs",
        module_name="nxtomomill.app.zstages2nxs",
        description="""creates all the target NXTomos for all the stages. Possibly reducing also reference scans for obtaining flats/dark""",
    )
    launcher.add_command(
        "h5-quick-start",
        module_name="nxtomomill.app.h5config",
        description="Create a default configuration file",
        deprecated_replacement="h5-config",
        deprecated_since_version=0.13,
    )
    launcher.add_command(
        "h5-config",
        module_name="nxtomomill.app.h5config",
        description="Create a default configuration file",
    )
    launcher.add_command(
        "split-nxfile",
        module_name="nxtomomill.app.split_nxfile",
        description="Split a file containing several NXtomo into a one file per NXtomo",
    )
    launcher.add_command(
        "fscan2nx",
        module_name="nxtomomill.app.fscan2nx",
        description="convert fscan hdf5 to nexus hdf5",
    )
    status = launcher.execute(sys.argv)
    return status


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