import os

from specs_parser import SpecsParser
from config import etcd_client as client
from config import VM_PREFIX


specs_parser = SpecsParser(exceptional_devices=["cpu"])


class Field:
    def __init__(self, _name, _type, _value=None):
        self.name = _name
        self.value = _value
        self.type = _type
        self.__errors = []

    def validation(self):
        return True

    def is_valid(self):
        if self.value == KeyError:
            self.add_error("'{}' field is a required field".format(self.name))
        else:
            if not isinstance(self.value, self.type):
                self.add_error("Incorrect Type for '{}' field".format(self.name))
            else:
                self.validation()

        if self.__errors:
            return False
        return True

    def get_errors(self):
        return self.__errors

    def add_error(self, error):
        self.__errors.append(error)


class VmUUIDField(Field):
    def __init__(self, data):
        self.uuid = data.get("uuid", KeyError)

        super().__init__("uuid", str, self.uuid)

        self.validation = self.vm_uuid_validation

    def vm_uuid_validation(self):
        r = client.get(os.path.join(VM_PREFIX, self.uuid))
        if not r:
            self.add_error("VM with uuid {} does not exists".format(self.uuid))


class SpecsField(Field):
    def __init__(self, data):
        self.specs = data.get("specs", KeyError)

        super().__init__("specs", dict, self.specs)

        self.validation = self.specs_validation

    def specs_validation(self):
        if not specs_parser.transform_specs(self.specs):
            self.add_error("Invalid unit - "
                           "Please use following units {}".format(specs_parser.get_allowed_units()))