#
#   Copyright 2022 Logical Clocks AB
#
#   Licensed under the Apache License, Version 2.0 (the "License");
#   you may not use this file except in compliance with the License.
#   You may obtain a copy of the License at
#
#       http://www.apache.org/licenses/LICENSE-2.0
#
#   Unless required by applicable law or agreed to in writing, software
#   distributed under the License is distributed on an "AS IS" BASIS,
#   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
#   See the License for the specific language governing permissions and
#   limitations under the License.

import humps
from typing import List, Optional

from hsml import util


class PredictorState:
    """State of a predictor."""

    def __init__(
        self,
        available_predictor_instances: int,
        available_transformer_instances: Optional[int],
        hopsworks_inference_path: str,
        model_server_inference_path: str,
        internal_port: Optional[int],
        revision: Optional[int],
        deployed: Optional[bool],
        conditions: Optional[List[str]],
        status: str,
    ):
        self._available_predictor_instances = available_predictor_instances
        self._available_transformer_instances = available_transformer_instances
        self._hopsworks_inference_path = hopsworks_inference_path
        self._model_server_inference_path = model_server_inference_path
        self._internal_port = internal_port
        self._revision = revision
        self._deployed = deployed if deployed is not None else False
        self._conditions = conditions
        self._status = status

    def describe(self):
        """Print a description of the deployment state"""
        util.pretty_print(self)

    @classmethod
    def from_response_json(cls, json_dict):
        json_decamelized = humps.decamelize(json_dict)
        return PredictorState(*cls.extract_fields_from_json(json_decamelized))

    @classmethod
    def extract_fields_from_json(cls, json_decamelized):
        ai = util.extract_field_from_json(json_decamelized, "available_instances")
        ati = util.extract_field_from_json(
            json_decamelized, "available_transformer_instances"
        )
        hip = util.extract_field_from_json(json_decamelized, "hopsworks_inference_path")
        msip = util.extract_field_from_json(
            json_decamelized, "model_server_inference_path"
        )
        ipt = util.extract_field_from_json(json_decamelized, "internal_port")
        r = util.extract_field_from_json(json_decamelized, "revision")
        d = util.extract_field_from_json(json_decamelized, "deployed")
        c = util.extract_field_from_json(json_decamelized, "conditions")
        s = util.extract_field_from_json(json_decamelized, "status")

        return ai, ati, hip, msip, ipt, r, d, c, s

    def to_dict(self):
        json = {
            "availableInstances": self._available_predictor_instances,
            "hopsworksInferencePath": self._hopsworks_inference_path,
            "modelServerInferencePath": self._model_server_inference_path,
            "status": self._status,
        }

        if self._available_transformer_instances is not None:
            json[
                "availableTransformerInstances"
            ] = self._available_transformer_instances
        if self._internal_port is not None:
            json["internalPort"] = self._internal_port
        if self._revision is not None:
            json["revision"] = self._revision
        if self._deployed is not None:
            json["deployed"] = self._deployed
        if self._conditions is not None:
            json["conditions"] = self._conditions

        return json

    @property
    def available_predictor_instances(self):
        """Available predicotr instances."""
        return self._available_predictor_instances

    @property
    def available_transformer_instances(self):
        """Available transformer instances."""
        return self._available_transformer_instances

    @property
    def hopsworks_inference_path(self):
        """Inference path in the Hopsworks REST API."""
        return self._hopsworks_inference_path

    @property
    def model_server_inference_path(self):
        """Inference path in the model server"""
        return self.model_server_inference_path

    @property
    def internal_port(self):
        """Internal port for the predictor."""
        return self._internal_port

    @property
    def revision(self):
        """Last revision of the predictor."""
        return self._revision

    @property
    def deployed(self):
        """Whether the predictor is deployed or not."""
        return self._deployed

    @property
    def conditions(self):
        """Conditions of the current state of predictor."""
        return self._conditions

    @property
    def status(self):
        """Status of the predictor."""
        return self._status

    def __repr__(self):
        return f"PredictorState(status: {self.status!r})"

#
#   Copyright 2022 Logical Clocks AB
#
#   Licensed under the Apache License, Version 2.0 (the "License");
#   you may not use this file except in compliance with the License.
#   You may obtain a copy of the License at
#
#       http://www.apache.org/licenses/LICENSE-2.0
#
#   Unless required by applicable law or agreed to in writing, software
#   distributed under the License is distributed on an "AS IS" BASIS,
#   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
#   See the License for the specific language governing permissions and
#   limitations under the License.

import humps
from typing import List, Optional

from hsml import util


class PredictorState:
    """State of a predictor."""

    def __init__(
        self,
        available_predictor_instances: int,
        available_transformer_instances: Optional[int],
        hopsworks_inference_path: str,
        model_server_inference_path: str,
        internal_port: Optional[int],
        revision: Optional[int],
        deployed: Optional[bool],
        conditions: Optional[List[str]],
        status: str,
    ):
        self._available_predictor_instances = available_predictor_instances
        self._available_transformer_instances = available_transformer_instances
        self._hopsworks_inference_path = hopsworks_inference_path
        self._model_server_inference_path = model_server_inference_path
        self._internal_port = internal_port
        self._revision = revision
        self._deployed = deployed if deployed is not None else False
        self._conditions = conditions
        self._status = status

    def describe(self):
        """Print a description of the deployment state"""
        util.pretty_print(self)

    @classmethod
    def from_response_json(cls, json_dict):
        json_decamelized = humps.decamelize(json_dict)
        return PredictorState(*cls.extract_fields_from_json(json_decamelized))

    @classmethod
    def extract_fields_from_json(cls, json_decamelized):
        ai = util.extract_field_from_json(json_decamelized, "available_instances")
        ati = util.extract_field_from_json(
            json_decamelized, "available_transformer_instances"
        )
        hip = util.extract_field_from_json(json_decamelized, "hopsworks_inference_path")
        msip = util.extract_field_from_json(
            json_decamelized, "model_server_inference_path"
        )
        ipt = util.extract_field_from_json(json_decamelized, "internal_port")
        r = util.extract_field_from_json(json_decamelized, "revision")
        d = util.extract_field_from_json(json_decamelized, "deployed")
        c = util.extract_field_from_json(json_decamelized, "conditions")
        s = util.extract_field_from_json(json_decamelized, "status")

        return ai, ati, hip, msip, ipt, r, d, c, s

    def to_dict(self):
        json = {
            "availableInstances": self._available_predictor_instances,
            "hopsworksInferencePath": self._hopsworks_inference_path,
            "modelServerInferencePath": self._model_server_inference_path,
            "status": self._status,
        }

        if self._available_transformer_instances is not None:
            json[
                "availableTransformerInstances"
            ] = self._available_transformer_instances
        if self._internal_port is not None:
            json["internalPort"] = self._internal_port
        if self._revision is not None:
            json["revision"] = self._revision
        if self._deployed is not None:
            json["deployed"] = self._deployed
        if self._conditions is not None:
            json["conditions"] = self._conditions

        return json

    @property
    def available_predictor_instances(self):
        """Available predicotr instances."""
        return self._available_predictor_instances

    @property
    def available_transformer_instances(self):
        """Available transformer instances."""
        return self._available_transformer_instances

    @property
    def hopsworks_inference_path(self):
        """Inference path in the Hopsworks REST API."""
        return self._hopsworks_inference_path

    @property
    def model_server_inference_path(self):
        """Inference path in the model server"""
        return self.model_server_inference_path

    @property
    def internal_port(self):
        """Internal port for the predictor."""
        return self._internal_port

    @property
    def revision(self):
        """Last revision of the predictor."""
        return self._revision

    @property
    def deployed(self):
        """Whether the predictor is deployed or not."""
        return self._deployed

    @property
    def conditions(self):
        """Conditions of the current state of predictor."""
        return self._conditions

    @property
    def status(self):
        """Status of the predictor."""
        return self._status

    def __repr__(self):
        return f"PredictorState(status: {self.status!r})"

# #   Copyright 2022 Logical Clocks AB # #   Licensed under the Apache License, Version 2.0 (the "License"); #   you may not use this file except in compliance with the License. #   You may obtain a copy of the License at # #       http://www.apache.org/licenses/LICENSE-2.0 # #   Unless required by applicable law or agreed to in writing, software #   distributed under the License is distributed on an "AS IS" BASIS, #   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. #   See the License for the specific language governing permissions and #   limitations under the License. State of a predictor. Print a description of the deployment state Available predicotr instances. Available transformer instances. Inference path in the Hopsworks REST API. Inference path in the model server Internal port for the predictor. Last revision of the predictor. Whether the predictor is deployed or not. Conditions of the current state of predictor. Status of the predictor.