#!python

"""
packme is a python3 application for generating and running packer templates.

It works by generating packer manifest.json files out of manifest.yml files which contain the packer settings for the image to build.
"""

import argparse
import glob
import os
import shutil
import sys

from typing import List

from packme import Packman

class NotSudo(Exception):
    pass

def clean_templates_dir(templates_base_dir: str):
    """Removes all manifest.json files, packer_cache and builds directories found in
    templates directory
    """

    template_dirs = glob.glob(os.path.join(templates_base_dir,"*"))

    for template_dir in template_dirs:

        try:
            os.remove(os.path.join(template_dir,"manifest.json"))
        except FileNotFoundError:
            pass

        try:
            shutil.rmtree(os.path.join(template_dir,"builds"))
        except FileNotFoundError:
            pass
        except PermissionError:
            raise NotSudo("Only sudoers can remove builds directory")

        try:
            shutil.rmtree(os.path.join(template_dir,"packer_cache"))
        except FileNotFoundError:
            pass
        except PermissionError:
            raise NotSudo("Only sudoers can remove packer_cache directory")

def parse_args() -> argparse.Namespace:
    """Returns the argument namespace after command-line parsing.
    """

    parser = argparse.ArgumentParser(description="This is packme: a program for generating and running packer configuration(s)")
    parser.add_argument("--log", "-l", dest="log", action="store_true", help="log packer output")
    parser.add_argument("--key-rate", "-k", dest="key_rate", default="10", help="rate for automatic key entering (in ms)")
    parser.add_argument("--clean", "-c", dest="clean", action="store_true", help="clean up templates directories")
    parser.add_argument("--debug", "-d", dest="debug", action="store_true", help="debug mode (keep temporary files)")
    parser.add_argument("--run", "-r", dest="run", action="store_true", help="run packer after json manifest(s) generation")
    parser.add_argument("--templates-base-dir", "-t", dest="templates_base_dir", required=True, help="Templates base directory")
    parser.add_argument("--packages-base-dir", "-p", dest="packages_base_dir", help="Packages base directory")
    parser.add_argument("--selected-templates", "-s", dest="selected_templates", nargs="*", default=["*"], help="run packman on selected template(s)")
    parser.add_argument("--input", "-i", dest="input_file", help="YAML input file")
    args = parser.parse_args()

    return args
                
if __name__ == "__main__":

    # Parse command line arguments and fetch their values
    args : argparse.Namespace = parse_args()
    input_file : str = args.input_file
    run : bool = args.run
    templates_base_dir : str = args.templates_base_dir
    packages_base_dir : str = args.packages_base_dir
    selected_templates : List[str] = args.selected_templates
    clean : bool = args.clean
    debug : bool= args.debug
    log : bool = args.log
    key_rate : int = int(args.key_rate)

    # If --clean option is set, cleanup the templates dir (builds, packer_cache, manifest.json files and directories)
    if clean:
        clean_templates_dir(templates_base_dir)

    if not input_file:
        sys.exit(0)

    t = Packman.Packman(input_file, templates_base_dir, packages_base_dir)

    t.build(selected_templates=selected_templates, indent=4, separators=(',', ': '))

    if run:
        t.run(selected_templates=selected_templates, log = log, key_rate=key_rate)

    # If --debug option is set, keep temporary files and directories in templates dir (builds, packer_cache, manifest.json)
    if not debug:
        clean_templates_dir(templates_base_dir)


