#!/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 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')

    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",
                        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",
                        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()
