#!/usr/bin/env python3
# Copyright 2020 The Pigweed Authors
#
# 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
#
#     https://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.
"""Command line interface for arduino_builder."""

import argparse
import json
import logging
import os
import pprint
import shlex
import subprocess
import sys
from collections import OrderedDict
from pathlib import Path
from typing import List

from pw_arduino_build import core_installer, log
from pw_arduino_build.builder import ArduinoBuilder
from pw_arduino_build.file_operations import decode_file_json

_LOG = logging.getLogger(__name__)

_pretty_print = pprint.PrettyPrinter(indent=1, width=120).pprint
_pretty_format = pprint.PrettyPrinter(indent=1, width=120).pformat


class MissingArduinoCore(Exception):
    """Exception raised when an Arduino core can not be found."""


def list_boards_command(unused_args, builder):
    # list-boards subcommand
    # (does not need a selected board or default menu options)

    # TODO(tonymd): Print this sorted with auto-ljust columns
    longest_name_length = 0
    for board_name, board_dict in builder.board.items():
        if len(board_name) > longest_name_length:
            longest_name_length = len(board_name)
    longest_name_length += 2

    print("Board Name".ljust(longest_name_length), "Description")
    for board_name, board_dict in builder.board.items():
        print(board_name.ljust(longest_name_length), board_dict['name'])
    sys.exit(0)


def list_menu_options_command(args, builder):
    # List all menu options for the selected board.
    builder.select_board(args.board)

    print("All Options")
    all_options, all_column_widths = builder.get_menu_options()
    separator = "-" * (all_column_widths[0] + all_column_widths[1] + 2)
    print(separator)

    for name, description in all_options:
        print(name.ljust(all_column_widths[0] + 1), description)

    print("\nDefault Options")
    print(separator)

    menu_options, unused_col_widths = builder.get_default_menu_options()
    for name, description in menu_options:
        print(name.ljust(all_column_widths[0] + 1), description)


def show_command_print_string_list(args, string_list: List[str]):
    if string_list:
        join_token = "\n" if args.delimit_with_newlines else " "
        print(join_token.join(string_list))


def show_command_print_flag_string(args, flag_string):
    if args.delimit_with_newlines:
        flag_string_with_newlines = shlex.split(flag_string)
        print("\n".join(flag_string_with_newlines))
    else:
        print(flag_string)


def subtract_flags(flag_list_a: List[str],
                   flag_list_b: List[str]) -> List[str]:
    """Given two sets of flags return flags in a that are not in b."""
    flag_counts = OrderedDict()  # type: OrderedDict[str, int]
    for flag in flag_list_a + flag_list_b:
        flag_counts[flag] = flag_counts.get(flag, 0) + 1
    return [flag for flag in flag_list_a if flag_counts.get(flag, 0) == 1]


def run_command_lines(args, command_lines: List[str]):
    for command_line in command_lines:
        if not args.quiet:
            print(command_line)
        # TODO(tonymd): Exit with sub command exit code.
        command_line_args = shlex.split(command_line)
        process = subprocess.run(command_line_args,
                                 stdout=subprocess.PIPE,
                                 stderr=subprocess.STDOUT)
        if process.returncode != 0:
            _LOG.error('Command failed with exit code %d.', process.returncode)
            _LOG.error('Full command:')
            _LOG.error('')
            _LOG.error('  %s', command_line)
            _LOG.error('')
            _LOG.error('Process output:')
            print(flush=True)
            sys.stdout.buffer.write(process.stdout)
            print(flush=True)
            _LOG.error('')


def run_command(args, builder):
    """Run sub command function.

    Runs Arduino recipes.
    """

    if args.run_prebuilds:
        run_command_lines(args, builder.get_prebuild_steps())

    if args.run_link:
        line = builder.get_link_line()
        archive_file_path = args.run_link[0]  # pylint: disable=unused-variable
        object_files = args.run_link[1:]
        line = line.replace("{object_files}", " ".join(object_files), 1)
        run_command_lines(args, [line])

    if args.run_objcopy:
        run_command_lines(args, builder.get_objcopy_steps())

    if args.run_postbuilds:
        run_command_lines(args, builder.get_postbuild_steps())

    if args.run_upload_command:
        command = builder.get_upload_line(args.run_upload_command,
                                          args.serial_port)
        run_command_lines(args, [command])


# pylint: disable=too-many-branches
def show_command(args, builder):
    """Show sub command function.

    Prints compiler info and flags.
    """
    if args.cc_binary:
        print(builder.get_cc_binary())

    elif args.cxx_binary:
        print(builder.get_cxx_binary())

    elif args.objcopy_binary:
        print(builder.get_objcopy_binary())

    elif args.ar_binary:
        print(builder.get_ar_binary())

    elif args.size_binary:
        print(builder.get_size_binary())

    elif args.c_compile:
        print(builder.get_c_compile_line())

    elif args.cpp_compile:
        print(builder.get_cpp_compile_line())

    elif args.link:
        print(builder.get_link_line())

    elif args.objcopy:
        print(builder.get_objcopy(args.objcopy))

    elif args.objcopy_flags:
        objcopy_flags = builder.get_objcopy_flags(args.objcopy_flags)
        show_command_print_flag_string(args, objcopy_flags)

    elif args.c_flags:
        cflags = builder.get_c_flags()
        show_command_print_flag_string(args, cflags)

    elif args.s_flags:
        sflags = builder.get_s_flags()
        show_command_print_flag_string(args, sflags)

    elif args.s_only_flags:
        s_only_flags = subtract_flags(shlex.split(builder.get_s_flags()),
                                      shlex.split(builder.get_c_flags()))
        show_command_print_flag_string(args, " ".join(s_only_flags))

    elif args.cpp_flags:
        cppflags = builder.get_cpp_flags()
        show_command_print_flag_string(args, cppflags)

    elif args.cpp_only_flags:
        cpp_only_flags = subtract_flags(shlex.split(builder.get_cpp_flags()),
                                        shlex.split(builder.get_c_flags()))
        show_command_print_flag_string(args, " ".join(cpp_only_flags))

    elif args.ld_flags:
        ldflags = builder.get_ld_flags()
        show_command_print_flag_string(args, ldflags)

    elif args.ld_libs:
        show_command_print_flag_string(args, builder.get_ld_libs())

    elif args.ld_lib_names:
        show_command_print_flag_string(args,
                                       builder.get_ld_libs(name_only=True))

    elif args.ar_flags:
        ar_flags = builder.get_ar_flags()
        show_command_print_flag_string(args, ar_flags)

    elif args.core_path:
        print(builder.get_core_path())

    elif args.prebuilds:
        show_command_print_string_list(args, builder.get_prebuild_steps())

    elif args.postbuilds:
        show_command_print_string_list(args, builder.get_postbuild_steps())

    elif args.upload_command:
        print(builder.get_upload_line(args.upload_command, args.serial_port))

    elif args.upload_tools:
        tools = builder.get_upload_tool_names()
        for tool_name in tools:
            print(tool_name)

    elif args.library_include_dirs:
        show_command_print_string_list(args, builder.library_include_dirs())

    elif args.library_includes:
        show_command_print_string_list(args, builder.library_includes())

    elif args.library_c_files:
        show_command_print_string_list(args, builder.library_c_files())

    elif args.library_s_files:
        show_command_print_string_list(args, builder.library_s_files())

    elif args.library_cpp_files:
        show_command_print_string_list(args, builder.library_cpp_files())

    elif args.core_c_files:
        show_command_print_string_list(args, builder.core_c_files())

    elif args.core_s_files:
        show_command_print_string_list(args, builder.core_s_files())

    elif args.core_cpp_files:
        show_command_print_string_list(args, builder.core_cpp_files())

    elif args.variant_c_files:
        vfiles = builder.variant_c_files()
        if vfiles:
            show_command_print_string_list(args, vfiles)

    elif args.variant_s_files:
        vfiles = builder.variant_s_files()
        if vfiles:
            show_command_print_string_list(args, vfiles)

    elif args.variant_cpp_files:
        vfiles = builder.variant_cpp_files()
        if vfiles:
            show_command_print_string_list(args, vfiles)


def add_common_parser_args(parser, serial_port, build_path, build_project_name,
                           project_path, project_source_path):
    """Add command line options common to the run and show commands."""
    parser.add_argument(
        "--serial-port",
        default=serial_port,
        help="Serial port for flashing. Default: '{}'".format(serial_port))
    parser.add_argument(
        "--build-path",
        default=build_path,
        help="Build directory. Default: '{}'".format(build_path))
    parser.add_argument(
        "--project-path",
        default=project_path,
        help="Project directory. Default: '{}'".format(project_path))
    parser.add_argument(
        "--project-source-path",
        default=project_source_path,
        help="Project directory. Default: '{}'".format(project_source_path))
    parser.add_argument("--library-path",
                        default=[],
                        nargs="+",
                        type=str,
                        help="Path to Arduino Library directory.")
    parser.add_argument(
        "--build-project-name",
        default=build_project_name,
        help="Project name. Default: '{}'".format(build_project_name))
    parser.add_argument("--board",
                        required=True,
                        help="Name of the board to use.")
    # nargs="+" is one or more args, e.g:
    #   --menu-options menu.usb.serialhid menu.speed.150
    parser.add_argument(
        "--menu-options",
        nargs="+",
        type=str,
        metavar="menu.usb.serial",
        help="Desired Arduino menu options. See the "
        "'list-menu-options' subcommand for available options.")
    parser.add_argument("--set-variable",
                        action="append",
                        metavar='some.variable=NEW_VALUE',
                        help="Override an Arduino recipe variable. May be "
                        "specified multiple times. For example: "
                        "--set-variable 'serial.port.label=/dev/ttyACM0' "
                        "--set-variable 'serial.port.protocol=Teensy'")


def check_for_missing_args(args):
    if args.arduino_package_path is None:
        raise MissingArduinoCore(
            "Please specify the location of an Arduino core using "
            "'--arduino-package-path' and '--arduino-package-name'.")


# TODO(tonymd): These defaults don't make sense anymore and should be removed.
def get_default_options():
    defaults = {}
    defaults["build_path"] = os.path.realpath(
        os.path.expanduser(
            os.path.expandvars(os.path.join(os.getcwd(), "build"))))
    defaults["project_path"] = os.path.realpath(
        os.path.expanduser(os.path.expandvars(os.getcwd())))
    defaults["project_source_path"] = os.path.join(defaults["project_path"],
                                                   "src")
    defaults["build_project_name"] = os.path.basename(defaults["project_path"])
    defaults["serial_port"] = "UNKNOWN"
    return defaults


def load_config_file(args):
    """Load a config file and merge with command line options.

    Command line takes precedence over values loaded from a config file."""

    if args.save_config and not args.config_file:
        raise FileNotFoundError(
            "'--save-config' requires the '--config-file' option")

    if not args.config_file:
        return

    default_options = get_default_options()

    commandline_options = {
        # Global option
        "arduino_package_path": args.arduino_package_path,
        "arduino_package_name": args.arduino_package_name,
        "compiler_path_override": args.compiler_path_override,
        # These options may not exist unless show or run command
        "build_path": getattr(args, "build_path", None),
        "project_path": getattr(args, "project_path", None),
        "project_source_path": getattr(args, "project_source_path", None),
        "build_project_name": getattr(args, "build_project_name", None),
        "board": getattr(args, "board", None),
        "menu_options": getattr(args, "menu_options", None),
    }

    # Decode JSON config file.
    json_file_options, config_file_path = decode_file_json(args.config_file)

    # Merge config file with command line options.
    merged_options = {}
    for key, value in commandline_options.items():
        # Use the command line specified option by default
        merged_options[key] = value

        # Is this option in the config file?
        if json_file_options.get(key, None) is not None:
            # Use the json defined option if it's not set on the command
            # line (or is a default value).
            if value is None or value == default_options.get(key, None):
                merged_options[key] = json_file_options[key]

    # Update args namespace to matched merged_options.
    for key, value in merged_options.items():
        setattr(args, key, value)

    # Write merged_options if --save-config.
    if args.save_config:
        encoded_json = json.dumps(merged_options, indent=4)
        # Create parent directories
        os.makedirs(os.path.dirname(config_file_path), exist_ok=True)
        # Save json file.
        with open(config_file_path, "w") as jfile:
            jfile.write(encoded_json)


def _parse_args() -> argparse.Namespace:
    """Setup argparse and parse command line args."""
    def log_level(arg: str) -> int:
        try:
            return getattr(logging, arg.upper())
        except AttributeError:
            raise argparse.ArgumentTypeError(
                f'{arg.upper()} is not a valid log level')

    def existing_directory(input_string: str):
        """Argparse type that resolves to an absolute path."""
        input_path = Path(os.path.expandvars(input_string)).absolute()
        if not input_path.exists():
            raise argparse.ArgumentTypeError(
                "'{}' is not a valid directory.".format(str(input_path)))
        return input_path.as_posix()

    parser = argparse.ArgumentParser()
    parser.add_argument("-q",
                        "--quiet",
                        help="hide run command output",
                        action="store_true")
    parser.add_argument('-l',
                        '--loglevel',
                        type=log_level,
                        default=logging.INFO,
                        help='Set the log level '
                        '(debug, info, warning, error, critical)')

    default_options = get_default_options()

    # Global command line options
    parser.add_argument("--arduino-package-path",
                        type=existing_directory,
                        help="Path to the arduino IDE install location.")
    parser.add_argument("--arduino-package-name",
                        help="Name of the Arduino board package to use.")
    parser.add_argument("--compiler-path-override",
                        type=existing_directory,
                        help="Path to arm-none-eabi-gcc bin folder. "
                        "Default: Arduino core specified gcc")
    parser.add_argument("-c", "--config-file", help="Path to a config file.")
    parser.add_argument("--save-config",
                        action="store_true",
                        help="Save command line arguments to the config file.")

    # Subcommands
    subparsers = parser.add_subparsers(title="subcommand",
                                       description="valid subcommands",
                                       help="sub-command help",
                                       dest="subcommand",
                                       required=True)

    # install-core command
    install_core_parser = subparsers.add_parser(
        "install-core", help="Download and install arduino cores")
    install_core_parser.set_defaults(func=core_installer.install_core_command)
    install_core_parser.add_argument("--prefix",
                                     required=True,
                                     help="Path to install core files.")
    install_core_parser.add_argument(
        "--core-name",
        required=True,
        choices=core_installer.supported_cores(),
        help="Name of the arduino core to install.")

    # list-boards command
    list_boards_parser = subparsers.add_parser("list-boards",
                                               help="show supported boards")
    list_boards_parser.set_defaults(func=list_boards_command)

    # list-menu-options command
    list_menu_options_parser = subparsers.add_parser(
        "list-menu-options",
        help="show available menu options for selected board")
    list_menu_options_parser.set_defaults(func=list_menu_options_command)
    list_menu_options_parser.add_argument("--board",
                                          required=True,
                                          help="Name of the board to use.")

    # show command
    show_parser = subparsers.add_parser("show",
                                        help="Return compiler information.")
    add_common_parser_args(show_parser, default_options["serial_port"],
                           default_options["build_path"],
                           default_options["build_project_name"],
                           default_options["project_path"],
                           default_options["project_source_path"])
    show_parser.add_argument("--delimit-with-newlines",
                             help="Separate flag output with newlines.",
                             action="store_true")
    show_parser.add_argument("--library-names", nargs="+", type=str)

    output_group = show_parser.add_mutually_exclusive_group(required=True)
    output_group.add_argument("--c-compile", action="store_true")
    output_group.add_argument("--cpp-compile", action="store_true")
    output_group.add_argument("--link", action="store_true")
    output_group.add_argument("--c-flags", action="store_true")
    output_group.add_argument("--s-flags", action="store_true")
    output_group.add_argument("--s-only-flags", action="store_true")
    output_group.add_argument("--cpp-flags", action="store_true")
    output_group.add_argument("--cpp-only-flags", action="store_true")
    output_group.add_argument("--ld-flags", action="store_true")
    output_group.add_argument("--ar-flags", action="store_true")
    output_group.add_argument("--ld-libs", action="store_true")
    output_group.add_argument("--ld-lib-names", action="store_true")
    output_group.add_argument("--objcopy", help="objcopy step for SUFFIX")
    output_group.add_argument("--objcopy-flags",
                              help="objcopy flags for SUFFIX")
    output_group.add_argument("--core-path", action="store_true")
    output_group.add_argument("--cc-binary", action="store_true")
    output_group.add_argument("--cxx-binary", action="store_true")
    output_group.add_argument("--ar-binary", action="store_true")
    output_group.add_argument("--objcopy-binary", action="store_true")
    output_group.add_argument("--size-binary", action="store_true")
    output_group.add_argument("--prebuilds",
                              action="store_true",
                              help="Show prebuild step commands.")
    output_group.add_argument("--postbuilds",
                              action="store_true",
                              help="Show postbuild step commands.")
    output_group.add_argument("--upload-tools", action="store_true")
    output_group.add_argument("--upload-command")
    output_group.add_argument("--library-includes", action="store_true")
    output_group.add_argument("--library-include-dirs", action="store_true")
    output_group.add_argument("--library-c-files", action="store_true")
    output_group.add_argument("--library-s-files", action="store_true")
    output_group.add_argument("--library-cpp-files", action="store_true")
    output_group.add_argument("--core-c-files", action="store_true")
    output_group.add_argument("--core-s-files", action="store_true")
    output_group.add_argument("--core-cpp-files", action="store_true")
    output_group.add_argument("--variant-c-files", action="store_true")
    output_group.add_argument("--variant-s-files", action="store_true")
    output_group.add_argument("--variant-cpp-files", action="store_true")

    show_parser.set_defaults(func=show_command)

    # run command
    run_parser = subparsers.add_parser("run", help="Run Arduino recipes.")
    add_common_parser_args(run_parser, default_options["serial_port"],
                           default_options["build_path"],
                           default_options["build_project_name"],
                           default_options["project_path"],
                           default_options["project_source_path"])
    run_parser.add_argument("--run-link",
                            nargs="+",
                            type=str,
                            help="Run the link command. Expected arguments: "
                            "the archive file followed by all obj files.")
    run_parser.add_argument("--run-objcopy", action="store_true")
    run_parser.add_argument("--run-prebuilds", action="store_true")
    run_parser.add_argument("--run-postbuilds", action="store_true")
    run_parser.add_argument("--run-upload-command")

    run_parser.set_defaults(func=run_command)

    return parser.parse_args()


def main():
    """Main command line function.

    Dispatches command line invocations to sub `*_command()` functions.
    """
    # Parse command line arguments.
    args = _parse_args()
    _LOG.debug(_pretty_format(args))

    log.install(args.loglevel)

    # Check for and set alternate compiler path.
    if args.compiler_path_override:
        # Get absolute path
        compiler_path_override = os.path.realpath(
            os.path.expanduser(os.path.expandvars(
                args.compiler_path_override)))
        args.compiler_path_override = compiler_path_override

    load_config_file(args)

    if args.subcommand == "install-core":
        args.func(args)
    elif args.subcommand in ["list-boards", "list-menu-options"]:
        check_for_missing_args(args)
        builder = ArduinoBuilder(args.arduino_package_path,
                                 args.arduino_package_name)
        builder.load_board_definitions()
        args.func(args, builder)
    else:  # args.subcommand in ["run", "show"]
        check_for_missing_args(args)
        builder = ArduinoBuilder(
            args.arduino_package_path,
            args.arduino_package_name,
            build_path=args.build_path,
            build_project_name=args.build_project_name,
            project_path=args.project_path,
            project_source_path=args.project_source_path,
            library_path=getattr(args, 'library_path', None),
            library_names=getattr(args, 'library_names', None),
            compiler_path_override=args.compiler_path_override)
        builder.load_board_definitions()
        builder.select_board(args.board, args.menu_options)
        if args.set_variable:
            builder.set_variables(args.set_variable)
        args.func(args, builder)

    sys.exit(0)


if __name__ == '__main__':
    main()
