#!/usr/bin/env python3

# Simple LaTeX Utility
# sltx

# TODO: check versioning
# TODO: do not install if already done
# TODO: symlink options?
# TODO: add 'auto'/'noob' modus which will install lithie util (default-full dependencies) to the docker/whatever container (easier install/in docker too)
# TODO: dig mode given detailed informations about errors

import argparse
import os  # list directory
import sys  # cmd line args

from sltxpkg import globals as sg
import sltxpkg.util as su
from sltxpkg.commands import cmd_compile, cmd_raw_compile, cmd_dependency, cmd_gen_gha, cmd_docker, cmd_version, cmd_cleanse


def valid_file(arg: str) -> str:
    if arg is None or arg.strip() == "":
        raise ValueError("arg vas none or empty")
    if not os.path.isfile(arg):
        raise FileNotFoundError("\"" + arg + "\" must be an existing file")
    return arg


# TODO: cleanup arguments and automatically generate the stuff
commands = {
    'dependency': (cmd_dependency, ('dep')),
    'docker': (cmd_docker, ('do')),
    'compile': (cmd_compile, ('cmp')),
    'raw-compile': (cmd_raw_compile, ('raw-cmp')),
    'gen-gha': (cmd_gen_gha, ('gen')),
    'cleanse': (cmd_cleanse, ('cls')),
    'version': (cmd_version, ())}


parser = argparse.ArgumentParser(
    description="sltx, a Simple LaTeX utility", epilog="sltx Version: " + su.get_version())

cmd_parser = parser.add_subparsers(
    title='command', description="Select the command for sltx", metavar=set(commands.keys()),
    help="Help for the specific command. You may use shortcuts for them: " +
    str([k[1] for k in commands.values() if len(k[1]) != 0]),
    dest='command')

# TODO: cleanse caches
p_cleanse = cmd_parser.add_parser(
    'cleanse', description="This will clean all additional sltx-files in the current directory (like \"sltx-log-*\" files). It may clean more, if you pass the corresponding flags. Please note, that cleanse will only read the current config. If you've changed some configurations they will be used.", aliases=['cls'])

# TODO: clean more?
p_cleanse.add_argument('--all', dest='cleanse_all', action='store_true',
                    help="If set, sltx will clean the texmf-tree (sltx) as-well.")

p_cleanse.add_argument('-e', '--exclude', action='append', metavar='pattern', dest='exclude_patterns', 
                    help="Exclude all files/directories matching this pattern. May be supplied multiple times.")

p_docker = cmd_parser.add_parser(
    'docker', description='Manage the containers to compile with sltx.', aliases=['do'])

p_dependency = cmd_parser.add_parser(
    'dependency', description='Install dependencies on the host system.', aliases=['dep'])
p_dependency.add_argument('dep', metavar='dep.yml', type=valid_file,
                          help="the file to load the dependencies from.")

p_raw_compile = cmd_parser.add_parser(
    'raw-compile', description="Compile documents using a recipe. This will not start any docker container but will be executed inside one as well.", aliases=['raw-cmp'])

p_raw_compile.add_argument('-r', '--recipe', dest='recipe',
                           help='The recipe to instruct the main compile routine.', required=False, default=None)
p_raw_compile.add_argument('file', metavar='file.tex', type=str,
                           help="the file to load; it will be processed.")

p_compile = cmd_parser.add_parser(
    'compile', description="Compile documents with previously installed containers. If docker was disabled this will default to the same behavior as \"raw-compile\" passing on the recipe.", aliases=['cmp'])
# TODO:
# p_compile.add_argument('-d', '--dependency', nargs='1', metavar="dep.yml", dest='dep', )
# TODO: glossary etc.
p_compile.add_argument('-p', '--profile', dest='profile',
                       help="allows to override the configured docker profile. This will enable docker automatically.")
p_compile.add_argument('-r', '--recipe', dest='recipe',
                       help='The recipe to instruct the main compile routine.', required=False, default=None)

# TODO: filters:
# p_compile.add_argument('-i', '--isolate', action='store_true', dest='isolate', help="disables mounting the current fs. This will pass the file only. Has no effect if not using docker. Note that in isolation only the *.pdf will be returned")
p_compile.add_argument('file', metavar='file.tex', type=str,
                       help="the file to load; it will be processed.")

p_generate = cmd_parser.add_parser(
    'gen-gha', description='Generate a GitHub workflow To automate compilation.', aliases=['gen'])

# commands, parser.add_mutually_exclusive_group()
parser.add_argument('-c', '--config', dest='config', metavar='config.yml',
                    required=False, type=valid_file,
                    help="the file to load the configuration from.")

parser.add_argument('-t', '--threads', metavar='N', dest='threads', type=int,
                    help="number of threads to run the installation. Default is 1. This number will only affect some routines.",
                    default=1)

# parser.add_argument('-n', '--no-archive', dest='no_archive', action='store_true',
#                     help="If set, sltx won't create tar-balls in case of critical failures.")

p_version = cmd_parser.add_parser(
    'version', description='Show the version-info for sltx.')

if(len(sys.argv) <= 1):
    parser.parse_args(['-h'])

sg.args = parser.parse_args()

try:
    tc = sg.args.command.lower()
    # This is ugly, but it basically checks if tc is in the commands and if so, use that commands
    # if not it searches through the list of aliasses and if it finds one it will use this
    cmd = commands[tc][0] if tc in commands else commands[[alias[0]
                                                           for alias in commands.items() if tc in alias[1][1]][0]][0]
except KeyError:
    print("The supplied command:", sg.args.command,
          "is unknown. Choose one of:", list(commands.keys()))
    exit(1)

cmd()

# TODO: if no deps or no generate call
