# -*- coding: utf-8 -*-

import os
import time
import requests

from qiniu import compat
from qiniu import utils

UC_HOST = 'https://uc.qbox.me'      # 获取空间信息Host


class Zone(object):
    """七牛上传区域类

    该类主要内容上传区域地址。

    Attributes:
        up_host: 首选上传地址
        up_host_backup: 备用上传地址
    """
    def __init__(self, up_host=None, up_host_backup=None, io_host=None, host_cache={}, scheme="http"):
        """初始化Zone类"""
        self.up_host, self.up_host_backup, self.io_host = up_host, up_host_backup, io_host
        self.host_cache = host_cache
        self.scheme = scheme

    def get_up_host_by_token(self, up_token):
        ak, bucket = self.unmarshal_up_token(up_token)
        up_hosts = self.get_up_host(ak, bucket)
        return up_hosts[0]

    def get_up_host_backup_by_token(self, up_token):
        ak, bucket = self.unmarshal_up_token(up_token)
        up_hosts = self.get_up_host(ak, bucket)

        if (len(up_hosts) <= 1):
            up_host = up_hosts[0]
        else:
            up_host = up_hosts[1]
        return up_host

    def get_io_host(self, ak, bucket):
        bucket_hosts = self.get_bucket_hosts(ak, bucket)
        io_hosts = bucket_hosts['ioHosts']
        return io_hosts[0]

    def get_up_host(self, ak, bucket):
        bucket_hosts = self.get_bucket_hosts(ak, bucket)
        up_hosts = bucket_hosts['upHosts']
        return up_hosts

    def unmarshal_up_token(self, up_token):
        token = up_token.split(':')
        if(len(token) != 3):
            raise ValueError('invalid up_token')

        ak = token[0]
        policy = compat.json.loads(compat.s(utils.urlsafe_base64_decode(token[2])))

        scope = policy["scope"]
        bucket = scope
        if(':' in scope):
            bucket = scope.split(':')[0]

        return ak, bucket

    def get_bucket_hosts(self, ak, bucket):
        key = self.scheme + ":" + ak + ":" + bucket

        bucket_hosts = self.get_bucket_hosts_to_cache(key)
        if(len(bucket_hosts) > 0):
            return bucket_hosts

        hosts = compat.json.loads(self.bucket_hosts(ak, bucket))

        scheme_hosts = hosts[self.scheme]
        bucket_hosts = {
            'upHosts': scheme_hosts['up'],
            'ioHosts': scheme_hosts['io'],
            'deadline': int(time.time()) + hosts['ttl']
        }

        self.set_bucket_hosts_to_cache(key, bucket_hosts)

        return bucket_hosts

    def get_bucket_hosts_to_cache(self, key):
        ret = []
        if(len(self.host_cache) == 0):
            self.host_cache_from_file()

        if(not (key in self.host_cache)):
            return ret

        if(self.host_cache[key]['deadline'] > time.time()):
            ret = self.host_cache[key]

        return ret

    def set_bucket_hosts_to_cache(self, key, val):
        self.host_cache[key] = val
        self.host_cache_to_file()
        return

    def host_cache_from_file(self):
        path = self.host_cache_file_path()
        if not os.path.isfile(path):
            return None
        with open(path, 'r') as f:
            bucket_hosts = compat.json.load(f)
            self.host_cache = bucket_hosts
        f.close()
        return

    def host_cache_to_file(self):
        path = self.host_cache_file_path()
        with open(path, 'w') as f:
            compat.json.dump(self.host_cache, f)
        f.close()

    def host_cache_file_path(self):
        home = os.getenv("HOME")
        return home + "/.qiniu_pythonsdk_hostscache.json"

    def bucket_hosts(self, ak, bucket):
        url = "{0}/v1/query?ak={1}&bucket={2}".format(UC_HOST, ak, bucket)
        ret = requests.get(url)
        # ret, info = http._get(url, None, None)
        data = compat.json.dumps(ret.json(), separators=(',', ':'))
        return data
