# Copyright (c) 2019 Ultimaker B.V.
# Cura is released under the terms of the LGPLv3 or higher.
# Modified by BigRep GmbH 2024
from typing import List

from .BaseModel import BaseModel


class BigRepConnectOutputDeviceResponse(BaseModel):
    """Class representing a CONNECT output device response."""

    def __init__(self, output_device_data: dict, **kwargs) -> None:
        """Creates a new cluster response object.

        :param cluster_id: The secret unique ID, e.g. 'kBEeZWEifXbrXviO8mRYLx45P8k5lHVGs43XKvRniPg='.
        :param host_guid: The unique identifier of the print cluster host, e.g. 'e90ae0ac-1257-4403-91ee-a44c9b7e8050'.
        :param host_name: The name of the printer as configured during the Wi-Fi setup. Used as identifier for end users.
        :param is_online: Whether this cluster is currently connected to the cloud.
        :param status: The status of the cluster authentication (active or inactive).
        :param host_version: The firmware version of the cluster host. This is where the Stardust client is running on.
        :param host_internal_ip: The internal IP address of the host printer.
        :param friendly_name: The human readable name of the host printer.
        :param printer_type: The machine type of the host printer.
        :param printer_count: The amount of printers in the print cluster. 1 for a single printer
        """

        def get_nested_value(data, *keys, default=None):
            for key in keys:
                if data is None or key not in data or data[key] is None:  # Key change
                    return default
                data = data[key]
            return data

        self.serial_number = get_nested_value(output_device_data, 'printerCustomer', 'printer', 'serialNumber')
        self.name = get_nested_value(output_device_data, 'printerCustomer', 'customName')
        self.machine_type = self.applyMachineTypeMapping(get_nested_value(output_device_data, 'printerCustomer', 'printer', 'type'))
        self.firmware_version = get_nested_value(output_device_data, 'printerCustomer', 'printer', 'softwareBundle', 'firmwareVersion')
        super().__init__(**kwargs)

    # Maps the CONNECT machine type name to Blade
    def applyMachineTypeMapping(self, machine_type: str):
        machine_type_mapping = {
            "ONE_3": "bigrep_onev3",
            "ONE_4": "bigrep_one_4",
            "STUDIO": "bigrep_studio",
            "STUDIO_2": "bigrep_studio_g2",
            "VIIO": "bigrep_viio",
            }

        return machine_type_mapping.get(machine_type, None)
        
    # Validates the model, raising an exception if the model is invalid.
    def validate(self) -> None:
        super().validate()
        if not self.serial_number and self.machine_type:
            raise ValueError("Serial number and machine type is required on CloudCluster")