#!/usr/bin/env python
#
# Copyright (c) 2022 Project CHIP 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
#
# http://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.
#
"""OTA image generator

This script generates OTA image file from the input hex files.

The XS data would be compressed into OTA image with the given LZSS tool.

"""

import argparse
import pathlib
import subprocess
import sys
import zlib

from intelhex import IntelHex
from struct import pack, pack_into


def main():
    parser = argparse.ArgumentParser()
    parser.add_argument("--binary", required=True, type=pathlib.Path)
    parser.add_argument("--ds_hex", required=True, type=pathlib.Path)
    parser.add_argument("--xs_hex", required=True, type=pathlib.Path)
    parser.add_argument("--lzss_tool", required=True, type=pathlib.Path)
    parser.add_argument("--active_xs_len", required=True,
                        type=lambda x: int(x, 0))
    parser.add_argument("--upgrade_xs_len", required=True,
                        type=lambda x: int(x, 0))
    parser.add_argument("--project_config", required=True, type=pathlib.Path)
    parser.add_argument("--ota_image_tool", required=True, type=pathlib.Path)

    option = parser.parse_args()

    intel_hex = IntelHex(str(option.ds_hex))
    intel_hex.loadhex(str(option.xs_hex))
    ds_segment, xs_segment = intel_hex.segments()[0:2]

    ds_header = intel_hex.tobinarray(
        start=ds_segment[0], end=ds_segment[0] + 0x10 - 1)
    ds_data = intel_hex.tobinarray(
        start=ds_segment[0] + 0x10, end=ds_segment[1] - 1)
    xs_data = intel_hex.tobinarray(start=xs_segment[0], end=xs_segment[1] - 1)

    # Align to 4 bytes
    ds_data = pad_data(ds_data, 4)
    xs_data = pad_data(xs_data, 4)

    # Pad XS data CRC to DS data
    xs_crc = zlib.crc32(xs_data)
    ds_data += pack("<L", xs_crc)

    # Compressed data
    cx_data = compress_data(option, xs_data, ".xs.bin")
    cx_crc = zlib.crc32(cx_data)

    # DS header
    ds_crc = zlib.crc32(ds_data)
    pack_into("<LL", ds_header, 0x08, ds_crc, len(ds_data))

    # XS header
    xs_header = ds_header.tobytes()
    xs_header += pack("<LL", xs_crc, len(xs_data))
    xs_header += pack("<LL", cx_crc, len(cx_data))

    print("DS: Length 0x{:08x}, CRC 0x{:08x}".format(len(ds_data), ds_crc))
    print("XS: Length 0x{:08x}, CRC 0x{:08x}".format(len(xs_data), xs_crc))
    print("CX: Length 0x{:08x}, CRC 0x{:08x}".format(len(cx_data), cx_crc))

    print(
        "Active  XS: Used {:7,}, Free {:7,}".format(
            len(xs_data), option.active_xs_len - len(xs_data)
        )
    )
    upgrade_xs_len = len(xs_header) + len(cx_data)
    print(
        "Upgrade XS: Used {:7,}, Free {:7,}".format(
            upgrade_xs_len, option.upgrade_xs_len - upgrade_xs_len
        )
    )

    if option.upgrade_xs_len < upgrade_xs_len:
        print("Error: Insufficient space for the upgrade XS.")
        return -1

    gen_image(option, ds_header, ds_data, xs_header, cx_data)

    return 0


def compress_data(option, data, file_suffix):
    raw_file = str(option.binary.with_suffix(file_suffix))
    compressed_file = str(option.binary.with_suffix(file_suffix + ".lz"))

    with open(raw_file, mode="wb") as binary:
        binary.write(data)

    subprocess.run([option.lzss_tool, "e", raw_file,
                   compressed_file, ], check=True)

    with open(compressed_file, mode="rb") as binary:
        return binary.read()


def pad_data(data, aligned_size):
    data = bytearray(data)
    remained_length = len(data) % aligned_size
    if remained_length != 0:
        data += bytes(aligned_size - remained_length)
    return data


def gen_image(option, ds_header, ds_data, xs_header, cx_data):

    configs = parse_config(option)

    write_binary(option, ds_header, ds_data, xs_header, cx_data)
    run_ota_image_tool(option, configs)

    # Get the header size
    header_size = 0
    for line in subprocess.run(
        [option.ota_image_tool, "show", option.binary.with_suffix(".ota"), ],
        check=True,
        capture_output=True,
        text=True,
    ).stdout.splitlines():
        if line.startswith("Header Size:"):
            header_size = int(line.split(":")[1])
            break

    if header_size % 4 == 0:
        return

    # Insert zeroes to align sections to word
    inserted_zero_count = 4 - header_size % 4
    write_binary(option, ds_header, ds_data, xs_header,
                 cx_data, inserted_zero_count)
    run_ota_image_tool(option, configs)


def parse_config(option):
    configs = {}
    with open(option.project_config, "r") as config_file:
        for line in config_file.readlines():

            tokens = line.strip().split()
            if not tokens or not tokens[0].endswith("define"):
                continue

            key = tokens[1]
            value = tokens[2]

            if value.startswith('"'):
                configs[key] = value.strip('"')
            else:
                configs[key] = int(value, 0)

    return configs


def write_binary(option, ds_header, ds_data, xs_header, cx_data, inserted_zero_count=0):
    with open(str(option.binary), mode="wb") as binary:
        binary.write(bytes(inserted_zero_count))
        binary.write(ds_header)
        binary.write(ds_data)
        binary.write(xs_header)
        binary.write(cx_data)


def run_ota_image_tool(option, configs):
    subprocess.run(
        [
            option.ota_image_tool,
            "create",
            "--vendor-id={}".format(
                configs["CHIP_DEVICE_CONFIG_DEVICE_VENDOR_ID"]),
            "--product-id={}".format(
                configs["CHIP_DEVICE_CONFIG_DEVICE_PRODUCT_ID"]),
            "--version={}".format(
                configs["CHIP_DEVICE_CONFIG_DEVICE_SOFTWARE_VERSION"]
            ),
            "--version-str={}".format(
                configs["CHIP_DEVICE_CONFIG_DEVICE_SOFTWARE_VERSION_STRING"]
            ),
            "--digest-algorithm=sha256",
            option.binary,
            option.binary.with_suffix(".ota"),
        ],
        stderr=subprocess.STDOUT,
        check=True,
    )


if __name__ == "__main__":
    sys.exit(main())
