"""
SPDX-FileCopyrightText: 2020-present Open Networking Foundation <info@opennetworking.org>
SPDX-License-Identifier: LicenseRef-ONF-Member-1.01
"""

from __future__ import print_function

from collections import namedtuple
import logging as log
import os
import sys
import time
from argparse import ArgumentParser, SUPPRESS
from imutils import build_montages

import cv2
from openvino.inference_engine import IECore

from base_camera import BaseCamera

Shape = namedtuple('Shape', ['n','c','h','w'])

class Camera(BaseCamera):
    model = None
    prob_threshold = 0.0
    input = None
    device = None

    def __init__(self, device, args):
        log.basicConfig(format="[ %(levelname)s ] %(message)s", level=log.INFO, stream=sys.stdout)

        self.model_xml = args.model
        self.input = args.input
        self.prob_threshold = args.prob_threshold

        self.is_async_mode = True

        self.device = device

        super(Camera, self).__init__(device, args.idle)

    def __del__(self):
        # stream.release()
        cv2.destroyAllWindows()

    def init_stream(self):
        if self.input == 'cam':
            input_stream = 0
        elif self.input == 'gstreamer':
            input_stream = 'udpsrc port=500' + self.device + ' caps = " application/x-rtp, media=(string)video, clock-rate=(int)90000, encoding-name=(string)H264, payload=(int)96" ! rtph264depay ! avdec_h264 ! videoconvert ! appsink'
        else:
            input_stream = self.input
            assert os.path.isfile(self.input), "Specified input file doesn't exist"

        if self.input == 'gstreamer':
            stream = cv2.VideoCapture(input_stream, cv2.CAP_GSTREAMER)
        else:
            stream = cv2.VideoCapture(input_stream)

        return stream


    def init_inference(self):
        self.model_bin = os.path.splitext(self.model_xml)[0] + ".bin"

        # Read IR
        log.info("Reading IR...")
        net = IECore().read_network(model=self.model_xml, weights=self.model_bin)

        assert len(net.inputs.keys()) == 1, "Demo supports only single input topologies"
        assert len(net.outputs) == 1, "Demo supports only single output topologies"
        input_blob = next(iter(net.inputs))
        out_blob = next(iter(net.outputs))

        log.info("Loading IR to the plugin...")
        exec_net = IECore().load_network(network=net, device_name="CPU", num_requests=2)
        # Read and pre-process input image
        shape = Shape(*net.inputs[input_blob].shape)

        del net

        return exec_net, shape, input_blob, out_blob


    def frames(self):

        exec_net, shape, input_blob, out_blob  = self.init_inference()
        stream = self.init_stream()

        cur_request_id = 0
        next_request_id = 1

        # Async doesn't work if True
        # Request issues = Runtime Error: [REQUEST BUSY]
        # self.is_async_mode = False
        render_time = 0
        ret, frame = stream.read()

        while True:
            if self.is_async_mode:
                ret, next_frame = stream.read()
            else:
                ret, frame = stream.read()
            if not ret:
                break
            initial_w = stream.get(cv2.CAP_PROP_FRAME_WIDTH)
            initial_h = stream.get(cv2.CAP_PROP_FRAME_HEIGHT)

            # Main sync point:
            # in the truly Async mode we start the NEXT infer request, while waiting for the CURRENT to complete
            # in the regular mode we start the CURRENT request and immediately wait for it's completion
            inf_start = time.time()
            if self.is_async_mode:
                in_frame = cv2.resize(next_frame, (shape.w, shape.h))
                in_frame = in_frame.transpose((2, 0, 1))  # Change data layout from HWC to CHW
                in_frame = in_frame.reshape((shape.n, shape.c, shape.h, shape.w))
                exec_net.start_async(request_id=next_request_id, inputs={input_blob: in_frame})
            else:
                in_frame = cv2.resize(frame, (shape.w, shape.h))
                in_frame = in_frame.transpose((2, 0, 1))  # Change data layout from HWC to CHW
                in_frame = in_frame.reshape((shape.n, shape.c, shape.h, shape.w))
                exec_net.start_async(request_id=cur_request_id, inputs={input_blob: in_frame})

            if exec_net.requests[cur_request_id].wait(-1) == 0:
                inf_end = time.time()
                det_time = inf_end - inf_start

                # Parse detection results of the current request
                res = exec_net.requests[cur_request_id].outputs[out_blob]

                for obj in res[0][0]:
                    # Draw only objects when probability more than specified threshold
                    if obj[2] > self.prob_threshold:
                        xmin = int(obj[3] * initial_w)
                        ymin = int(obj[4] * initial_h)
                        xmax = int(obj[5] * initial_w)
                        ymax = int(obj[6] * initial_h)
                        class_id = int(obj[1])
                        # Draw box and label\class_id
                        color = (0, 0, 255)
                        cv2.rectangle(frame, (xmin, ymin), (xmax, ymax), color, 2)
                        det_label = str(class_id)
                        cv2.putText(frame, det_label + ' ' + str(round(obj[2] * 100, 1)) + ' %', (xmin, ymin - 7),
                                    cv2.FONT_HERSHEY_COMPLEX, 0.6, color, 1)

                cv2.putText(frame, self.device, (10, int(initial_h - 20)),
                        cv2.FONT_HERSHEY_COMPLEX, 0.5, (10, 10, 200), 1)

            render_start = time.time()

            yield cv2.imencode('.jpg', frame)[1].tobytes()

            render_end = time.time()
            render_time = render_end - render_start

            if self.is_async_mode:
                cur_request_id, next_request_id = next_request_id, cur_request_id
                frame = next_frame
