# Copyright 3D Control Systems, Inc. All Rights Reserved 2017-2019.
# Built in San Francisco.

# This software is distributed under a commercial license for personal,
# educational, corporate or any other use.
# The software as a whole or any parts of it is prohibited for distribution or
# use without obtaining a license from 3D Control Systems, Inc.

# All software licenses are subject to the 3DPrinterOS terms of use
# (available at https://www.3dprinteros.com/terms-and-conditions/),
# and privacy policy (available at https://www.3dprinteros.com/privacy-policy/)

import sys
import time
import logging

try:
    from io import StringIO
except:
    from io import StringIO

import log
from dual_cam import Camera


class M5thCamera(Camera):
    def __init__(self, parent):
        self.parent = parent
        self.ip = parent.ip
        self.cloud_camera_number = None
        Camera.__init__(self)

    def pre_init(self):
        self.logger = logging.getLogger(__name__)

    def init_user_token(self):
        self.user_token = self.parent.parent.parent.user_login.user_token
        self.http_client.mac = self.parent.parent.parent.user_login.mac

    def init(self):
        Camera.init(self)
        self.min_loop_time = 1

    def start(self):
        return

    @log.log_exception
    def main_loop(self):
        self.init_parameters()
        self.resized.append(True)
        self.fails.append(0)
        if not self.ip:
            self.logger.error('No IP. Stopping...')
            return
        self.makerbot = self.parent.makerbot
        self.cloud_camera_number = self.get_number_by_ip()
        time.sleep(self.min_loop_time)
        while not self.stop_flag and not self.parent.stop_flag:
            self.logger.info("camera %s cycle" % self.cloud_camera_number)
            frame_start_time = time.monotonic()
            frame = self.make_shot()
            if frame:
                # self.logger.debug("Got frame from camera N" + str(number))
                self.send_frame(frame)
            else:
                self.logger.warning("No frame from camera N" + str(self.cloud_camera_number))
            while time.monotonic() < frame_start_time + 0.001 + self.min_loop_time:
                time.sleep(0.01)
        self.http_client.close()
        sys.exit(0)

    def get_number_by_ip(self):
        data = self.ip.split(".")
        for i, item in enumerate(data):
            data[i] = item.zfill(3)
        return int(''.join(data))

    def get_camera_number_for_cloud(self):
        return self.cloud_camera_number

    def make_shot(self):
        if self.is_same_image_frame():
            return self.SAME_IMAGE_FRAME
        _, width, height, type, image_data = self.makerbot._get_raw_camera_image_data()
        if not image_data:
            self.logger.warning('Failed to get camera frame: %i, %i' % (width, height))
            return None
        if type == 1:
            bgr_rows = self.makerbot.yuv_to_bgr_rows(StringIO(image_data), width, height)
            frame = self.np.array(bgr_rows).reshape(height, width, 3)
            return self.get_image_from_cv2_frame(self.resize_cv2_frame(frame))
        elif type == 2:
            return self.resize_image(image_data)
        self.logger.warning('Failed to get camera frame (wrong type): %i, %i, %i' % (width, height, type))
        return None
