"""
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
from argparse import ArgumentParser, SUPPRESS
from imutils import build_montages

import cv2
from openvino.inference_engine import IECore

from base_camera import BaseCamera


class Camera(BaseCamera):
    Shape = namedtuple('Shape', ['n','c','h','w'])

    def __init__(self, device, client, args):
        self.model_xml = args.model
        self.input = args.input
        self.prob_threshold = args.prob_threshold
        self.is_async_mode = True
        self.device = device
        self.client = client
        super(Camera, self).__init__(device, args.key, args.mbrlow, args.mbrhigh, args.devicegroup, args.noroc)

    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 output-corrupt=false ! 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 = Camera.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

        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
            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:

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

                initial_w = 640
                initial_h = 480
                frame = cv2.resize(frame, (initial_w, initial_h))

                obj_count = 0
                red = (0, 0, 255)
                black = (0, 0, 0)
                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)
                        # Draw box and prob
                        cv2.rectangle(frame, (xmin, ymin), (xmax, ymax), red, 2)
                        cv2.putText(frame, str(round(obj[2] * 100, 1)) + ' %', (xmin, ymin - 7),
                                    cv2.FONT_HERSHEY_COMPLEX, 0.6, black, 1)
                        obj_count += 1

                cv2.putText(frame, "persons: {}".format(str(obj_count)), (10, 20),
                        cv2.FONT_HERSHEY_COMPLEX, 0.6, black, 1)
                cv2.putText(frame, "camera: {}".format(self.device), (10, int(initial_h - 20)),
                        cv2.FONT_HERSHEY_COMPLEX, 0.6, black, 1)

                if obj_count > 0:
                    self.person_detected(obj_count)

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

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