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

from __future__ import print_function

import cv2
import logging as log
import os
import sys
import time
from argparse import ArgumentParser, SUPPRESS
from imutils import build_montages
from openvino.inference_engine import IECore
from base_camera import BaseCamera


def build_argparser():
    parser = ArgumentParser(add_help=False)
    args = parser.add_argument_group('Options')
    args.add_argument('-h', '--help', action='help', default=SUPPRESS, help='Show this help message and exit.')
    args.add_argument("-m", "--model", help="Required. Path to an .xml file with a trained model.",
                      required=True, type=str)
    args.add_argument("-i", "--input",
                      help="Required. Path to video file or image. 'cam' for capturing video stream from camera",
                      required=True, type=str)
    args.add_argument("-l", "--cpu_extension",
                      help="Optional. Required for CPU custom layers. Absolute path to a shared library with the "
                           "kernels implementations.", type=str, default=None)
    args.add_argument("-pp", "--plugin_dir", help="Optional. Path to a plugin folder", type=str, default=None)
    args.add_argument("-d", "--device",
                      help="Optional. Specify the target device to infer on; CPU, GPU, FPGA, HDDL or MYRIAD is "
                           "acceptable. The demo will look for a suitable plugin for device specified. "
                           "Default value is CPU", default="CPU", type=str)
    args.add_argument("--labels", help="Optional. Path to labels mapping file", default=None, type=str)
    args.add_argument("-pt", "--prob_threshold", help="Optional. Probability threshold for detections filtering",
                      default=0.5, type=float)
    args.add_argument("-ns", help='No show output', action='store_true')

    return parser


class Camera(BaseCamera):

    def __init__(self, device, args):
        log.basicConfig(format="[ %(levelname)s ] %(message)s", level=log.INFO, stream=sys.stdout)
        model_xml = args.model
        model_bin = os.path.splitext(model_xml)[0] + ".bin"

        # Read IR
        log.info("Reading IR...")
        net = IECore().read_network(model=model_xml, weights=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"
        self.input_blob = next(iter(net.inputs))
        self.out_blob = next(iter(net.outputs))

        log.info("Loading IR to the plugin...")
        self.exec_net = IECore().load_network(network=net, device_name=args.device, num_requests=2)
        # Read and pre-process input image
        self.n, self.c, self.h, self.w = net.inputs[self.input_blob].shape
        del net
        if args.input == 'cam':
            self.input_stream = 0
        elif args.input == 'gstreamer':
            # gst rtp sink
            self.input_stream = 'udpsrc port=500' + device + ' caps = " application/x-rtp, encoding-name=JPEG,payload=26" ! rtpjpegdepay ! decodebin ! videoconvert ! appsink'
            #input_stream = 'udpsrc port=5000 caps = "application/x-rtp, media=(string)video, clock-rate=(int)90000, encoding-name=(string)H264, payload=(int)96" ! rtph264depay ! decodebin ! videoconvert ! appsink'
            print("input_stream:", self.input_stream)
        else:
            self.input_stream = args.input
            assert os.path.isfile(args.input), "Specified input file doesn't exist"

        if args.labels:
            with open(args.labels, 'r') as f:
                self.labels_map = [x.strip() for x in f]
        else:
            self.labels_map = None

        self.args = args

        super(Camera, self).__init__(device)

    def __del__(self):
        self.cap.release()
        cv2.destroyAllWindows()

    def frames(self):

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

        cur_request_id = 0
        next_request_id = 1

        log.info("Starting inference in async mode...")
        log.info("To switch between sync and async modes press Tab button")
        log.info("To stop the demo execution press Esc button")

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

        print("To close the application, press 'CTRL+C' or any key with focus on the output window")

        while True:
            if self.is_async_mode:
                ret, next_frame = self.cap.read()
            else:
                ret, frame = self.cap.read()
            if not ret:
                break
            initial_w = self.cap.get(3)
            initial_h = self.cap.get(4)

            # 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, (self.w, self.h))
                in_frame = in_frame.transpose((2, 0, 1))  # Change data layout from HWC to CHW
                in_frame = in_frame.reshape((self.n, self.c, self.h, self.w))
                self.exec_net.start_async(request_id=next_request_id, inputs={self.input_blob: in_frame})
            else:
                in_frame = cv2.resize(frame, (self.w, self.h))
                in_frame = in_frame.transpose((2, 0, 1))  # Change data layout from HWC to CHW
                in_frame = in_frame.reshape((self.n, self.c, self.h, self.w))
                self.exec_net.start_async(request_id=cur_request_id, inputs={self.input_blob: in_frame})

            if self.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 = self.exec_net.requests[cur_request_id].outputs[self.out_blob]

                for obj in res[0][0]:
                    # Draw only objects when probability more than specified threshold
                    if obj[2] > self.args.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 = (min(class_id * 12.5, 255),min(class_id * 7, 255), min(class_id * 5, 255))
                        cv2.rectangle(frame, (xmin, ymin), (xmax, ymax), color, 2)
                        det_label = self.labels_map[class_id] if self.labels_map else 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)
                        # print('Object detected, class_id:', class_id, 'probability:', obj[2], 'xmin:', xmin, 'ymin:', ymin,
                        #      'xmax:', xmax, 'ymax:', ymax)

                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


if __name__ == '__main__':
    args = build_argparser().parse_args()
    camera = Camera(args)
    camera.frames()
    del camera
