#!/usr/bin/env python3
# Copyright 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
#
#      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.
"""Run a live camera stream from Nexus board
"""

import argparse
from datetime import datetime
from functools import reduce
import re
import subprocess
import serial
from PIL import Image, ImageDraw, ImageFont


def main():
    """Args:
      smc_uart_port: SMC uart port
      usb_serial: USB serial
      baudrate: Baud rate of smc uart
      input_shape: Input image shape
      input_mode: Input image mode
  """
    parser = argparse.ArgumentParser(
        description='Generate inputs for ML models.')
    parser.add_argument("--smc_uart_port",
                        required=True,
                        help="SMC uart port")
    parser.add_argument("--usb_serial", required=True, help="USB serial")
    parser.add_argument("--baudrate",
                        "-b",
                        default=115200,
                        type=int,
                        help='Baud rate of smc uart (example: 115200)')
    parser.add_argument("--input_shape",
                        "-s",
                        default=[320, 240],
                        nargs='+',
                        type=int,
                        help='Input image shape (example: "320 240")')
    parser.add_argument("--input_mode",
                        "-m",
                        default="L",
                        help='Input image mode (example: "RGB")')
    parser.add_argument("--opentitantool_bin", type=str, required=True)
    parser.add_argument("--opentitantool_conf", type=str, required=True)
    args = parser.parse_args()

    ser = serial.Serial(port=args.smc_uart_port, baudrate=args.baudrate)

    while True:
        line = ser.readline()
        try:
            if "Start of a frame" not in line.decode():
                # Drop the current frame and process the next available frame.
                continue
        except:
            continue
        address = re.search(r"\[SMC\] Start of a frame, address (\d+)\.",
                           line.decode())
        if address:
            address = address.groups(1)[0]
        else:
            continue
        current_time = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
        print("Start loading the frame")
        # Load the frame from uart
        byte_size = str(reduce(lambda x, y: x * y, args.input_shape))
        byte_str = subprocess.check_output([
            args.opentitantool_bin, '--conf', args.opentitantool_conf,
            '--interface', 'nexus', '--usb-serial', args.usb_serial, 'spi',
            'read-memory', '--length', byte_size, '--start', address
        ])

        im_obj = Image.frombytes(mode=args.input_mode,
                                 size=tuple(args.input_shape),
                                 data=byte_str)
        im_width = args.input_shape[0]
        im_height = args.input_shape[1]

        # Fetch the scores
        while (line := ser.readline()) and ("Score" not in line.decode()):
            continue
        scores = re.search(r"\[SMC\] Score 0: (-?\d+), Score 1: (-?\d+)\.",
                           line.decode())
        if scores:
            score_0 = scores.group(1)
            score_1 = scores.group(2)
        else:
            score_0 = "Err"
            score_1 = "Err"

        # Draw the image
        draw = ImageDraw.Draw(im_obj)
        text = f"Score 0: {score_0:4}, Score 1: {score_1:4}"
        font = ImageFont.load_default()
        draw.text((im_width * 0.95 - font.getlength(text), im_height * 0.90),
                  text=text,
                  fill=255)
        # Add timestamp
        current_time = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
        draw.text(
            (im_width * 0.95 - font.getlength(current_time), im_height * 0.05),
            text=current_time,
            fill=255)

        im_obj.save('/tmp/HPS_DEMO.png')
        print("Finish the frame at", current_time)
        print(text)
        print('-' * 40)


if __name__ == "__main__":
    main()
