#!/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.
"""Arduino Core Installer."""

import argparse
import logging
import os
import platform
import stat
import sys
import shutil
import subprocess
from typing import Dict

import pw_arduino_build.file_operations as file_operations

_LOG = logging.getLogger(__name__)

# yapf: disable
_ARDUINO_CORE_ARTIFACTS: Dict[str, Dict] = {
    # pylint: disable=line-too-long
    "teensy": {
        "Linux": {
            "arduino-ide": {
                "url": "https://downloads.arduino.cc/arduino-1.8.13-linux64.tar.xz",
                "file_name": "arduino-1.8.13-linux64.tar.xz",
                "sha256": "1b20d0ec850a2a63488009518725f058668bb6cb48c321f82dcf47dc4299b4ad",
            },
            "teensyduino": {
                "url": "https://www.pjrc.com/teensy/td_153/TeensyduinoInstall.linux64",
                "file_name": "TeensyduinoInstall.linux64",
                "sha256": "2e6cd99a757bc80593ea3de006de4cc934bcb0a6ec74cad8ec327f0289d40f0b",
            },
        },
        # TODO(tonymd): Handle 32-bit Linux Install?
        "Linux32": {
            "arduino-ide": {
                "url": "https://downloads.arduino.cc/arduino-1.8.13-linux32.tar.xz",
                "file_name": "arduino-1.8.13-linux32.tar.xz",
                "sha256": "",
            },
            "teensyduino": {
                "url": "https://www.pjrc.com/teensy/td_153/TeensyduinoInstall.linux32",
                "file_name": "TeensyduinoInstall.linux32",
                "sha256": "",
            },
        },
        # TODO(tonymd): Handle ARM32 (Raspberry Pi) Install?
        "LinuxARM32": {
            "arduino-ide": {
                "url": "https://downloads.arduino.cc/arduino-1.8.13-linuxarm.tar.xz",
                "file_name": "arduino-1.8.13-linuxarm.tar.xz",
                "sha256": "",
            },
            "teensyduino": {
                "url": "https://www.pjrc.com/teensy/td_153/TeensyduinoInstall.linuxarm",
                "file_name": "TeensyduinoInstall.linuxarm",
                "sha256": "",
            },
        },
        # TODO(tonymd): Handle ARM64 Install?
        "LinuxARM64": {
            "arduino-ide": {
                "url": "https://downloads.arduino.cc/arduino-1.8.13-linuxaarch64.tar.xz",
                "file_name": "arduino-1.8.13-linuxaarch64.tar.xz",
                "sha256": "",
            },
            "teensyduino": {
                "url": "https://www.pjrc.com/teensy/td_153/TeensyduinoInstall.linuxaarch64",
                "file_name": "TeensyduinoInstall.linuxaarch64",
                "sha256": "",
            },
        },
        "Darwin": {
            "teensyduino": {
                "url": "https://www.pjrc.com/teensy/td_153/Teensyduino_MacOS_Catalina.zip",
                "file_name": "Teensyduino_MacOS_Catalina.zip",
                "sha256": "401ef42c6e83e621cdda20191a4ef9b7db8a214bede5a94a9e26b45f79c64fe2",
            },
        },
        "Windows": {
            "arduino-ide": {
                "url": "https://downloads.arduino.cc/arduino-1.8.13-windows.zip",
                "file_name": "arduino-1.8.13-windows.zip",
                "sha256": "78d3e96827b9e9b31b43e516e601c38d670d29f12483e88cbf6d91a0f89ef524",
            },
            "teensyduino": {
                "url": "https://www.pjrc.com/teensy/td_153/TeensyduinoInstall.exe",
                "file_name": "TeensyduinoInstall.exe",
                "sha256": "88f58681e5c4772c54e462bc88280320e4276e5b316dcab592fe38d96db990a1",
            },
        }
    },
    "adafruit-samd": {
        "all": {
            "core": {
                "version": "1.6.2",
                "url": "https://github.com/adafruit/ArduinoCore-samd/archive/1.6.2.tar.gz",
                "sha256": "5875f5bc05904c10e6313f02653f28f2f716db639d3d43f5a1d8a83d15339d64",
            }
        },
        "Linux": {},
        "Darwin": {},
        "Windows": {},
    },
    "arduino-samd": {
        "all": {
            "core": {
                "version": "1.8.8",
                "url": "http://downloads.arduino.cc/cores/samd-1.8.8.tar.bz2",
                "file_name": "samd-1.8.8.tar.bz2",
                "sha256": "7b93eb705cba9125d9ee52eba09b51fb5fe34520ada351508f4253abbc9f27fa",
            }
        },
        "Linux": {},
        "Darwin": {},
        "Windows": {},
    },
    "stm32duino": {
        "all": {
            "core": {
                "version": "1.9.0",
                "url": "https://github.com/stm32duino/Arduino_Core_STM32/archive/1.9.0.tar.gz",
                "sha256": "4f75ba7a117d90392e8f67c58d31d22393749b9cdd3279bc21e7261ec06c62bf",
            }
        },
        "Linux": {},
        "Darwin": {},
        "Windows": {},
    },
}
# yapf: enable


def install_core_command(args: argparse.Namespace):
    install_prefix = os.path.realpath(
        os.path.expanduser(os.path.expandvars(args.prefix)))
    install_dir = os.path.join(install_prefix, args.core_name)
    cache_dir = os.path.join(install_prefix, ".cache", args.core_name)

    if args.core_name in supported_cores():
        shutil.rmtree(install_dir, ignore_errors=True)
        os.makedirs(install_dir, exist_ok=True)
        os.makedirs(cache_dir, exist_ok=True)

    if args.core_name == "teensy":
        if platform.system() == "Linux":
            install_teensy_core_linux(install_prefix, install_dir, cache_dir)
        elif platform.system() == "Darwin":
            install_teensy_core_mac(install_prefix, install_dir, cache_dir)
        elif platform.system() == "Windows":
            install_teensy_core_windows(install_prefix, install_dir, cache_dir)
    elif args.core_name == "adafruit-samd":
        install_adafruit_samd_core(install_prefix, install_dir, cache_dir)
    elif args.core_name == "stm32duino":
        install_stm32duino_core(install_prefix, install_dir, cache_dir)
    elif args.core_name == "arduino-samd":
        install_arduino_samd_core(install_prefix, install_dir, cache_dir)
    else:
        _LOG.error("Invalid core '%s'. Supported cores: %s", args.core_name,
                   ", ".join(supported_cores()))
        sys.exit(1)


def supported_cores():
    return _ARDUINO_CORE_ARTIFACTS.keys()


def install_teensy_core_windows(install_prefix, install_dir, cache_dir):
    """Download and install Teensyduino artifacts for Windows."""
    teensy_artifacts = _ARDUINO_CORE_ARTIFACTS["teensy"][platform.system()]

    arduino_artifact = teensy_artifacts["arduino-ide"]
    arduino_zipfile = file_operations.download_to_cache(
        url=arduino_artifact["url"],
        expected_sha256sum=arduino_artifact["sha256"],
        cache_directory=cache_dir)

    teensyduino_artifact = teensy_artifacts["teensyduino"]
    teensyduino_installer = file_operations.download_to_cache(
        url=teensyduino_artifact["url"],
        expected_sha256sum=teensyduino_artifact["sha256"],
        cache_directory=cache_dir)

    file_operations.extract_archive(arduino_zipfile, install_dir, cache_dir)

    # "teensy" here should match args.core_name
    teensy_core_dir = os.path.join(install_prefix, "teensy")

    # Change working directory for installation
    original_working_dir = os.getcwd()
    os.chdir(install_prefix)

    _LOG.info("Installing Teensyduino to: %s", teensy_core_dir)

    install_command = [teensyduino_installer, "--dir=teensy"]
    _LOG.info("  Running: %s", " ".join(install_command))
    _LOG.info("  Please click yes on the Windows 'User Account Control' "
              "dialog.")
    _LOG.info("  You should see: 'Verified publisher: PRJC.COM LLC'")

    install_command = [teensyduino_installer, "--dir=teensy"]
    subprocess.run(install_command)
    if not os.path.exists(os.path.join(teensy_core_dir, "hardware", "teensy")):
        _LOG.error(
            "Error: Installation Failed.\n"
            "Please try again and ensure Teensyduino is installed in "
            "the folder:\n"
            "%s", teensy_core_dir)
        sys.exit(1)
    else:
        _LOG.info("  Install complete!")

    file_operations.remove_empty_directories(install_dir)
    os.chdir(original_working_dir)


def install_teensy_core_mac(unused_install_prefix, install_dir, cache_dir):
    """Download and install Teensyduino artifacts for Mac."""
    teensy_artifacts = _ARDUINO_CORE_ARTIFACTS["teensy"][platform.system()]

    teensyduino_artifact = teensy_artifacts["teensyduino"]
    teensyduino_zip = file_operations.download_to_cache(
        url=teensyduino_artifact["url"],
        expected_sha256sum=teensyduino_artifact["sha256"],
        cache_directory=cache_dir)

    extracted_files = file_operations.extract_archive(
        teensyduino_zip,
        install_dir,
        cache_dir,
        remove_single_toplevel_folder=False)
    toplevel_folder = sorted(extracted_files)[0]
    os.symlink(os.path.join(toplevel_folder, "Contents", "Java", "hardware"),
               os.path.join(install_dir, "hardware"),
               target_is_directory=True)


def install_teensy_core_linux(install_prefix, install_dir, cache_dir):
    """Download and install Teensyduino artifacts for Windows."""
    teensy_artifacts = _ARDUINO_CORE_ARTIFACTS["teensy"][platform.system()]

    arduino_artifact = teensy_artifacts["arduino-ide"]
    arduino_tarfile = file_operations.download_to_cache(
        url=arduino_artifact["url"],
        expected_sha256sum=arduino_artifact["sha256"],
        cache_directory=cache_dir)

    teensyduino_artifact = teensy_artifacts["teensyduino"]
    teensyduino_installer = file_operations.download_to_cache(
        url=teensyduino_artifact["url"],
        expected_sha256sum=teensyduino_artifact["sha256"],
        cache_directory=cache_dir)

    extracted_files = file_operations.extract_archive(arduino_tarfile,
                                                      install_dir, cache_dir)
    os.chmod(teensyduino_installer,
             os.stat(teensyduino_installer).st_mode | stat.S_IEXEC)

    original_working_dir = os.getcwd()
    os.chdir(install_prefix)
    # "teensy" here should match args.core_name
    install_command = [teensyduino_installer, "--dir=teensy"]
    subprocess.run(install_command)

    # Remove original arduino IDE files
    for efile in extracted_files:
        if efile.is_file():
            efile.unlink()

    file_operations.remove_empty_directories(install_dir)
    os.chdir(original_working_dir)


def install_arduino_samd_core(install_prefix: str, install_dir: str,
                              cache_dir: str):
    artifacts = _ARDUINO_CORE_ARTIFACTS["arduino-samd"]["all"]["core"]
    core_tarfile = file_operations.download_to_cache(
        url=artifacts["url"],
        expected_sha256sum=artifacts["sha256"],
        cache_directory=cache_dir)

    package_path = os.path.join(install_dir, "hardware", "samd",
                                artifacts["version"])
    os.makedirs(package_path, exist_ok=True)
    file_operations.extract_archive(core_tarfile, package_path, cache_dir)
    original_working_dir = os.getcwd()
    os.chdir(install_prefix)
    # TODO(tonymd): Fetch core/tools as specified by:
    # http://downloads.arduino.cc/packages/package_index.json
    os.chdir(original_working_dir)
    return True


def install_adafruit_samd_core(install_prefix: str, install_dir: str,
                               cache_dir: str):
    artifacts = _ARDUINO_CORE_ARTIFACTS["adafruit-samd"]["all"]["core"]
    core_tarfile = file_operations.download_to_cache(
        url=artifacts["url"],
        expected_sha256sum=artifacts["sha256"],
        cache_directory=cache_dir)

    package_path = os.path.join(install_dir, "hardware", "samd",
                                artifacts["version"])
    os.makedirs(package_path, exist_ok=True)
    file_operations.extract_archive(core_tarfile, package_path, cache_dir)

    original_working_dir = os.getcwd()
    os.chdir(install_prefix)
    # TODO(tonymd): Fetch platform specific tools as specified by:
    # https://adafruit.github.io/arduino-board-index/package_adafruit_index.json
    # Specifically:
    #   https://github.com/ARM-software/CMSIS_5/archive/5.4.0.tar.gz
    os.chdir(original_working_dir)
    return True


def install_stm32duino_core(install_prefix, install_dir, cache_dir):
    artifacts = _ARDUINO_CORE_ARTIFACTS["stm32duino"]["all"]["core"]
    core_tarfile = file_operations.download_to_cache(
        url=artifacts["url"],
        expected_sha256sum=artifacts["sha256"],
        cache_directory=cache_dir)

    package_path = os.path.join(install_dir, "hardware", "stm32",
                                artifacts["version"])
    os.makedirs(package_path, exist_ok=True)
    file_operations.extract_archive(core_tarfile, package_path, cache_dir)
    original_working_dir = os.getcwd()
    os.chdir(install_prefix)
    # TODO(tonymd): Fetch platform specific tools as specified by:
    # https://github.com/stm32duino/BoardManagerFiles/raw/master/STM32/package_stm_index.json
    os.chdir(original_working_dir)
    return True
