#!/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 file.

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("--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.hex))
    ds_segment, xs_segment = intel_hex.segments()[1:3]

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