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

import os
import re
import shutil
import codecs
import hashlib
import chardet
import json
import stat
import subprocess
from .Config import g_conf
from .Router import Router
from enum import Enum


class Color(Enum):
    BLACK = 30
    RED = 31
    GREEN = 32
    YELLOW = 33
    BLUE = 34
    MAGENTA = 35
    CYAN = 36
    WHITE = 37


def print_color(text: str, fg: Color = Color.BLACK.value, end='\n'):
    print('\033[%sm%s\033[0m' % (fg, text), end=end)

def run(command, cwd):
    with subprocess.Popen(command, cwd=cwd, shell=True) as ret:
        ret.wait()
        if ret.returncode != 0:
            ret.kill()
            raise BaseException

def logged_func(delim='\n'):
    def inner(func):
        def wrapper(*args, **kwargs):
            log_start(func.__name__, delim)
            func(*args, **kwargs)
            log_end()
        return wrapper
    return inner


def copytree(src, dst, syamlinks=False, ignore=None):
    for item in os.listdir(src):
        s = unify_joinpath(src, item)
        d = unify_joinpath(dst, item)
        if os.path.isdir(s):
            shutil.copytree(s, d, syamlinks, ignore)
        else:
            shutil.copy2(s, d)


def force_rmtree(top):
    for root, dirs, files in os.walk(top, topdown=False):
        for name in files:
            filename = os.path.join(root, name)
            os.chmod(filename, stat.S_IWUSR)
            os.remove(filename)
        for name in dirs:
            os.rmdir(os.path.join(root, name))
    os.rmdir(top)


def log_start(message, delim):
    print_color('Start ' + message, Color.YELLOW.value, end='...'+delim)


def log_end():
    print_color('done.', Color.YELLOW.value)


def safe_write(path, content, codec="utf-8"):
    if not os.path.exists(os.path.dirname(path)):
        os.makedirs(os.path.dirname(path))

    with codecs.open(path, "w+", encoding=codec) as f:
        f.write(content)


def safe_read(path):
    if not os.path.exists(path):
        return ""

    # utf-8 is prefered
    try:
        with open(path, 'r', encoding='utf-8') as f:
            return f.read()
    except UnicodeDecodeError:
        with open(path, 'rb') as f:
            content = f.read()
            encoding = chardet.detect(content)['encoding'] or 'utf-8'
            return content.decode(encoding=encoding)


def gen_hash(str):
    h1 = hashlib.md5()
    h1.update(str.encode(encoding='utf-8'))
    return h1.hexdigest()


def unify_joinpath(left, right):
    path = os.path.join(left, right)
    return path.replace('\\', '/')


def filterPlaceholders(content):
    """replace content like ${key} to corresponding value

    1. search key in env
    2. search key in config
    """
    pattern = re.compile(r'[\s\S]*?\$\{([\s\S]*?)\}')
    router = Router(g_conf)

    def getKey(str):
        m = pattern.match(str)
        if not m is None:
            return m.group(1)
        else:
            return None

    while True:
        key = getKey(content)
        if key is None:
            break

        search_str = '${%s}' % key
        value = ''
        if key == "static_prefix":
            value = router.gen_static_file_prefix()
        else:
            # find in os.env
            value = os.getenv(key, None)
            if value is None:
                # find in config
                try:
                    value = getattr(g_conf, key)
                except AttributeError:
                    pass

        # replace
        content = content.replace(search_str, str(value), 1)

    return content
