# Copyright 2021-2023 Google LLC
#
# 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.

# -----------------------------------------------------------------------------
# Imports
# -----------------------------------------------------------------------------
import logging
import pathlib
import urllib.request
import urllib.error

import click

from bumble.colors import color
from bumble.drivers import rtk
from bumble.tools import rtk_util


# -----------------------------------------------------------------------------
# Logging
# -----------------------------------------------------------------------------
logger = logging.getLogger(__name__)


# -----------------------------------------------------------------------------
# Constants
# -----------------------------------------------------------------------------
LINUX_KERNEL_GIT_SOURCE = (
    "https://git.kernel.org/pub/scm/linux/kernel/git/firmware/linux-firmware.git/plain/rtl_bt",
    False,
)
REALTEK_OPENSOURCE_SOURCE = (
    "https://github.com/Realtek-OpenSource/android_hardware_realtek/raw/rtk1395/bt/rtkbt/Firmware/BT",
    True,
)
LINUX_FROM_SCRATCH_SOURCE = (
    "https://anduin.linuxfromscratch.org/sources/linux-firmware/rtl_bt",
    False,
)


# -----------------------------------------------------------------------------
# Functions
# -----------------------------------------------------------------------------
def download_file(base_url, name, remove_suffix):
    if remove_suffix:
        name = name.replace(".bin", "")

    url = f"{base_url}/{name}"
    with urllib.request.urlopen(url) as file:
        data = file.read()
        print(f"Downloaded {name}: {len(data)} bytes")
        return data


# -----------------------------------------------------------------------------
@click.command
@click.option(
    "--output-dir",
    default="",
    help="Output directory where the files will be saved. Defaults to the OS-specific"
    "app data dir, which the driver will check when trying to find firmware",
    show_default=True,
)
@click.option(
    "--source",
    type=click.Choice(["linux-kernel", "realtek-opensource", "linux-from-scratch"]),
    default="linux-kernel",
    show_default=True,
)
@click.option("--single", help="Only download a single image set, by its base name")
@click.option("--force", is_flag=True, help="Overwrite files if they already exist")
@click.option("--parse", is_flag=True, help="Parse the FW image after saving")
def main(output_dir, source, single, force, parse):
    """Download RTK firmware images and configs."""

    # Check that the output dir exists
    if output_dir == '':
        output_dir = rtk.rtk_firmware_dir()
    else:
        output_dir = pathlib.Path(output_dir)
    if not output_dir.is_dir():
        print("Output dir does not exist or is not a directory")
        return

    base_url, remove_suffix = {
        "linux-kernel": LINUX_KERNEL_GIT_SOURCE,
        "realtek-opensource": REALTEK_OPENSOURCE_SOURCE,
        "linux-from-scratch": LINUX_FROM_SCRATCH_SOURCE,
    }[source]

    print("Downloading")
    print(color("FROM:", "green"), base_url)
    print(color("TO:", "green"), output_dir)

    if single:
        images = [(f"{single}_fw.bin", f"{single}_config.bin", True)]
    else:
        images = [
            (driver_info.fw_name, driver_info.config_name, driver_info.config_needed)
            for driver_info in rtk.Driver.DRIVER_INFOS
        ]

    for fw_name, config_name, config_needed in images:
        print(color("---", "yellow"))
        fw_image_out = output_dir / fw_name
        if not force and fw_image_out.exists():
            print(color(f"{fw_image_out} already exists, skipping", "red"))
            continue
        if config_name:
            config_image_out = output_dir / config_name
            if not force and config_image_out.exists():
                print(color("f{config_out} already exists, skipping", "red"))
                continue

        try:
            fw_image = download_file(base_url, fw_name, remove_suffix)
        except urllib.error.HTTPError as error:
            print(f"Failed to download {fw_name}: {error}")
            continue

        config_image = None
        if config_name:
            try:
                config_image = download_file(base_url, config_name, remove_suffix)
            except urllib.error.HTTPError as error:
                if config_needed:
                    print(f"Failed to download {config_name}: {error}")
                    continue
                else:
                    print(f"No config available as {config_name}")

        fw_image_out.write_bytes(fw_image)
        if parse and config_name:
            print(color("Parsing:", "cyan"), fw_name)
            rtk_util.do_parse(fw_image_out)
        if config_image:
            config_image_out.write_bytes(config_image)


# -----------------------------------------------------------------------------
if __name__ == '__main__':
    main()
