#!/usr/bin/env python
# -*- coding:utf-8 -*-
from argparse import ArgumentParser, ArgumentTypeError, Namespace, RawTextHelpFormatter  # noqa: F401
from json import load as loadjson, dump as dumpjson
from logging import error
from os import stat, environ
from time import time

import sys


__cli_args = {}  # type: Namespace
__config = {}  # type: dict


def str2bool(v):
    """
    parse string to boolean
    """
    if isinstance(v, bool):
        return v
    if v.lower() in ('yes', 'true', 't', 'y', '1'):
        return True
    elif v.lower() in ('no', 'false', 'f', 'n', '0'):
        return False
    else:
        raise ArgumentTypeError('Boolean value expected.')


def init_config(description, doc, version):
    """
    配置
    """
    global __cli_args
    parser = ArgumentParser(description=description,
                            epilog=doc, formatter_class=RawTextHelpFormatter)
    parser.add_argument('-v', '--version',
                        action='version', version=version)
    parser.add_argument('-c', '--config', help="run with config file [配置文件路径]")

    # 参数定义
    parser.add_argument('--dns', help="DNS Provider [DNS服务提供商]", choices=[
                        'alidns', 'cloudflare', 'dnscom', 'dnspod', 'dnspod_com', 'he', 'huaweidns', 'callback'])
    parser.add_argument('--id', help="api ID [授权账户]")
    parser.add_argument('--token', help="api token or Secret key [授权访问凭证或密钥]")
    parser.add_argument('--ipv4', nargs="*",
                        help="ipv4 domain list [IPV4域名列表]")
    parser.add_argument('--ipv6', nargs="*",
                        help="ipv6 domain list [IPV6域名列表]")
    parser.add_argument('--index4', help="the way to get ipv4 [IPV4 获取方式]")
    parser.add_argument('--index6', help="the way to get ipv6 [IPV6获取方式]")
    parser.add_argument('--ttl', type=int, help="ttl for DNS [DNS 解析 TTL 时间]")
    parser.add_argument('--proxy', nargs="*",
                        help="https proxy [设置http 代理，多代理逐个尝试直到成功]")
    parser.add_argument('--debug',  type=str2bool, nargs='?',
                        const=True, help="debug mode [是否开启调试,默认否]", )
    parser.add_argument('--cache',  type=str2bool, nargs='?',
                        const=True, help="enable cache [是否缓存记录,默认是]")

    __cli_args = parser.parse_args()
    is_configfile_optional = get_config("token") or get_config("id")
    config_file = get_config("config")
    if not is_configfile_optional or config_file is not None:
        __load_config(config_file or "config.json", is_configfile_optional)
        __cli_args.config = config_file or "config.json"


def __load_config(path="config.json", skip_auto_generation=False):
    """
    加载配置
    """
    global __config
    try:
        with open(path) as configfile:
            __config = loadjson(configfile)
            __config["config_modified_time"] = stat(path).st_mtime
    except IOError:
        if skip_auto_generation:
            __config["config_modified_time"] = time()
            return
        error(' Config file `%s` does not exist!' % path)
        with open(path, 'w') as configfile:
            configure = {
                "$schema": "https://ddns.newfuture.cc/schema/v2.8.json",
                "id": "YOUR ID or EMAIL for DNS Provider",
                "token": "YOUR TOKEN or KEY for DNS Provider",
                "dns": "dnspod",
                "ipv4": [
                    "newfuture.cc",
                    "ddns.newfuture.cc"
                ],
                "ipv6": [
                    "newfuture.cc",
                    "ipv6.ddns.newfuture.cc"
                ],
                "index4": "default",
                "index6": "default",
                "ttl": None,
                "proxy": None,
                "debug": False,
            }
            dumpjson(configure, configfile, indent=2, sort_keys=True)
            sys.stdout.write(
                "New template configure file `%s` is generated.\n" % path)
            sys.exit(1)
    except Exception:
        sys.exit('fail to load config from file: %s' % path)


def get_config(key, default=None):
    """
    读取配置
    1. 命令行参数
    2. 配置文件
    3. 环境变量
    """
    if hasattr(__cli_args, key) and getattr(__cli_args, key) is not None:
        return getattr(__cli_args, key)
    if key in __config:
        return __config.get(key)
    env_name = 'DDNS_'+key.upper()  # type:str
    if env_name in environ:  # 大写环境变量
        return environ.get(env_name)
    if env_name.lower() in environ:  # 小写环境变量
        return environ.get(env_name.lower())
    return default
