#!/usr/bin/env python

#
# Copyright (c) Memfault, Inc.
# See LICENSE for details
#


"""
A script which transforms the memfault-firmware-sdk into a project suitable for inclusion as an arduino library

For more details about the arduino library see:
  https://arduino.github.io/arduino-cli/0.20/library-specification/

The main transformations this script makes:
 - Removes .c & .cpp files that should not be included in an arduino build. (The arduino build system
   will by default recursively search and compile all .c/.cpp files in the library folder)
 - Patches all include paths to be relative to the root of the library. (There is no way to add
   additional include paths in an arduino library)

Example Usage:
  $ python create_arduino_library.py --tag 0.28.2 --output build
"""

import argparse
import glob
import logging
import os
import re
import shutil
import tarfile
import urllib.request
from urllib.error import HTTPError

ROOT_DIRECTORY = os.path.dirname(os.path.dirname(os.path.realpath(__file__)))
BUILD_DIRECTORY = os.path.join(ROOT_DIRECTORY, "build")

MEMFAULT_RELEASE_PATH = "https://github.com/memfault/memfault-firmware-sdk/archive/refs/tags"


def download_memfault_library(working_dir: str, tag: str):
    release_artifact_filename = f"{tag}.tar.gz"
    release_artifact_filepath = os.path.join(working_dir, release_artifact_filename)
    logging.debug("Downloading %s ...", release_artifact_filename)
    try:
        urllib.request.urlretrieve(  # noqa: S310
            f"{MEMFAULT_RELEASE_PATH}/{release_artifact_filename}", release_artifact_filepath
        )
    except HTTPError as err:
        if err.code != 404:
            raise
        logging.error("No memfault-firmware-sdk with tag %s exists", tag)
        return None

    return release_artifact_filepath


def extract_memfault_library(working_dir: str, release_artifact_filepath: str):
    logging.debug("Extracting %s", release_artifact_filepath)
    download = tarfile.open(release_artifact_filepath)  # noqa: SIM115
    download.extractall(working_dir)  # noqa: S202
    root_folder_name = download.getnames()[0]
    download.close()
    extract_dir = os.path.realpath(os.path.join(working_dir, root_folder_name))
    logging.debug("Data extracted to %s", extract_dir)
    return extract_dir


def arduinoify_memfault_sdk(sdk_root_dir: str, result_dir: str, port: str):
    if not os.path.exists(sdk_root_dir):
        raise FileNotFoundError(f"Memfault SDK directory does not exist: {sdk_root_dir}")

    # We will be re-package'ing the SDK into a library with the following structure:
    #
    # |-- LICENSE
    # |-- README.md (sourced from port_dir if provided)
    # |-- examples (sourced from port_dir if provided)
    # |
    # |-- library.properties (sourced from port_dir if provided)
    # |-- src
    #    |-- memfault-firmware-sdk
    #    |--
    library_dir = os.path.join(result_dir)

    if port:
        port_dir = os.path.join(sdk_root_dir, "ports", port)
        if not os.path.exists(port_dir):
            logging.error("No port found for '%s' at %s", port, port_dir)
        else:
            logging.debug("Copying port from %s into %s", port_dir, library_dir)
            shutil.copytree(port_dir, library_dir)

    # After directory copy because it gets upset if file exists
    os.makedirs(library_dir, exist_ok=True)

    # Keep list for "ports" directory
    keep_list = ("panics",)
    port_root = os.path.join(sdk_root_dir, "ports")
    for f in os.listdir(port_root):
        if f in keep_list:
            continue
        path_to_rm = os.path.join(port_root, f)
        if not os.path.isdir(path_to_rm):
            continue
        logging.debug("Removing %s from memfault-firmware-sdk", path_to_rm)
        shutil.rmtree(path_to_rm)

    # Remove directories that aren't needed / contain .c / .cpp files we
    # do not want to compile
    remove_list = (".circleci", "examples", "tests")
    for directory in remove_list:
        path_to_rm = os.path.join(sdk_root_dir, directory)
        logging.debug("Removing %s from memfault-firmware-sdk", path_to_rm)
        shutil.rmtree(path_to_rm)

    files_to_patch = glob.glob(f"{sdk_root_dir}/**/*.c", recursive=True)
    files_to_patch.extend(glob.glob(f"{sdk_root_dir}/**/*.h", recursive=True))
    # also the memfault/metrics/heartbeat_config.def file
    files_to_patch.extend(
        glob.glob(f"{sdk_root_dir}/**/include/memfault/metrics/heartbeat_config.def")
    )

    logging.debug("Patching headers ...")

    # We need to swap out include paths to be relative to root of repo
    # since there's no way to add additional include paths in an arduino lib
    header_regex = re.compile(r'#include\s"memfault/')
    for f in files_to_patch:
        with open(f) as r:
            contents = r.read()
            contents = header_regex.sub(
                '#include "memfault-firmware-sdk/components/include/memfault/', contents
            )

        with open(f, "w") as w:
            w.write(contents)

    # Up level a few files to the root of the repo
    shutil.move(os.path.join(sdk_root_dir, "LICENSE"), os.path.join(library_dir, "LICENSE.txt"))
    shutil.move(os.path.join(sdk_root_dir, "VERSION"), os.path.join(library_dir, "VERSION"))
    shutil.move(
        os.path.join(sdk_root_dir, "CHANGELOG.md"), os.path.join(library_dir, "CHANGELOG.md")
    )
    shutil.move(sdk_root_dir, os.path.join(library_dir, "src", "memfault-firmware-sdk"))

    logging.debug("Patched SDK Generation Success! %s", library_dir)
    return library_dir


if __name__ == "__main__":
    logging.basicConfig(level=logging.INFO)
    parser = argparse.ArgumentParser(
        formatter_class=argparse.ArgumentDefaultsHelpFormatter,
        description="""
Transforms the memfault-firmware-sdk into a project suitable for inclusion in an arduino library.

Example Usage:

# cd into directory with .project file
$ python create_arduino_library.py --tag 0.28.2 --output build
""",
    )
    parser.add_argument(
        "-t",
        "--tag",
        required=False,
        help='The release from https://github.com/memfault/memfault-firmware-sdk/releases to convert to an arduino library (i.e "0.28.2")',
    )
    parser.add_argument(
        "-m",
        "--memfault-sdk",
        required=False,
        help="Path to .tar.gz of the memfault-firmware-sdk to convert to an arduino library",
    )
    parser.add_argument(
        "-o",
        "--output",
        help="The directory to output result to. By default a build/ directory relative to script location",
        default=os.path.join(BUILD_DIRECTORY, "arduino-library"),
    )

    parser.add_argument(
        "-p",
        "--port",
        help="Additional porting layer to include in the arduino library",
        default=None,
    )

    parser.add_argument(
        "-v",
        "--verbose",
        default=False,
        action="store_true",
        help="enable verbose logging for debug",
    )

    args = parser.parse_args()

    if args.tag and args.memfault_sdk:
        raise ValueError("--tag and --memfault-sdk can not be used together")

    if not args.tag and not args.memfault_sdk:
        raise ValueError("Either --tag or --memfault-sdk must be specified")

    # Create output directory if it does not exist
    os.makedirs(BUILD_DIRECTORY, exist_ok=True)

    if args.verbose:
        logging.getLogger().setLevel(logging.DEBUG)

    if args.tag:
        release_artifact_filepath = download_memfault_library(BUILD_DIRECTORY, args.tag)
        extraction_working_dir = BUILD_DIRECTORY
    else:
        release_artifact_filepath = args.memfault_sdk
        extraction_working_dir = os.path.join(BUILD_DIRECTORY, "memfault-firmware-sdk")

    assert release_artifact_filepath
    release_artifact_dir = extract_memfault_library(
        extraction_working_dir, release_artifact_filepath
    )

    result_dir = arduinoify_memfault_sdk(release_artifact_dir, args.output, args.port)

    logging.info("Hurray, library created at %s", result_dir)
