# coding: utf-8

from __future__ import absolute_import
from __future__ import division
from __future__ import unicode_literals

from .resource import NannyResource


class ShardInfo(NannyResource):
    __slots__ = ('chosen_type', 'containers_settings', )

    def __init__(self, local_path=None, chosen_type=None, containers_settings=None, **kwargs):
        self.chosen_type = chosen_type
        self.containers_settings = containers_settings
        super(ShardInfo, self).__init__(local_path, **kwargs)


class RegisteredShard(ShardInfo):
    __slots__ = ('shard_id', )
    CHOSEN_TYPE = 'REGISTERED_SHARD'

    def __init__(self, registered_shard, **kwargs):
        self.shard_id = str(registered_shard['shard_id'])

        kwargs_chosen_type = kwargs.pop('chosen_type', self.CHOSEN_TYPE)
        if kwargs_chosen_type != self.CHOSEN_TYPE:
            self.LOGGER.error('RegisteredShard __init__ got chosen_type %s instead of %s', kwargs_chosen_type, self.CHOSEN_TYPE)
        super(RegisteredShard, self).__init__(chosen_type=self.CHOSEN_TYPE, **kwargs)

    def dict(self):
        base_dict = super(RegisteredShard, self).dict()
        del base_dict['shard_id']
        base_dict['registered_shard'] = {'shard_id': self.shard_id}
        return base_dict


class SandboxShard(ShardInfo):
    __slots__ = ('task_type', 'task_id', 'resource_type', )
    CHOSEN_TYPE = 'SANDBOX_SHARD'

    def __init__(self, task_type, task_id, resource_type, **kwargs):
        self.task_type = task_type
        self.task_id = str(task_id)
        self.resource_type = resource_type

        kwargs_chosen_type = kwargs.pop('chosen_type', self.CHOSEN_TYPE)
        if kwargs_chosen_type != self.CHOSEN_TYPE:
            self.LOGGER.error('SandboxShard __init__ got chosen_type %s instead of %s', kwargs_chosen_type, self.CHOSEN_TYPE)
        super(SandboxShard, self).__init__(chosen_type=self.CHOSEN_TYPE, **kwargs)


class SandboxShardmap(ShardInfo):
    __slots__ = ('task_type', 'task_id', 'resource_type', )
    CHOSEN_TYPE = 'SANDBOX_SHARDMAP'

    def __init__(self, sandbox_shardmap, **kwargs):
        self.task_type = sandbox_shardmap['task_type']
        self.task_id = str(sandbox_shardmap['task_id'])
        self.resource_type = sandbox_shardmap['resource_type']

        kwargs_chosen_type = kwargs.pop('chosen_type', self.CHOSEN_TYPE)
        if kwargs_chosen_type != self.CHOSEN_TYPE:
            self.LOGGER.error('SandboxShardmap __init__ got chosen_type %s instead of %s', kwargs_chosen_type, self.CHOSEN_TYPE)
        super(SandboxShardmap, self).__init__(chosen_type=self.CHOSEN_TYPE, **kwargs)

    def dict(self):
        base_dict = super(SandboxShardmap, self).dict()
        for s in self.__slots__:
            del base_dict[s]
        base_dict['sandbox_shardmap'] = {k: getattr(self, k) for k in self.__slots__}
        return base_dict


def sandbox_bsc_shard(shard_info):
    shard_type_mapping = {
        'REGISTERED_SHARD': RegisteredShard, 'SANDBOX_SHARD': SandboxShard, 'SANDBOX_SHARDMAP': SandboxShardmap
    }
    if shard_info is None:
        return None
    else:
        return shard_type_mapping[shard_info['chosen_type']](**shard_info)
