#!/usr/bin/env python3
# -*- coding:utf-8 -*-
from inc import CliTool
import os, json, sys

##获取发布的idc机器列表
def get_idc_host_file(idc, app = None, is_web = False, only_sw = False):
    idc = idc.lower()

    ##阿里云
    if idc == 'aliyun8':
        return 'hosts/hosts-honor8-vpc.txt'

def get_pubish_module(app, env):
    if env == 'pre':
        if app in [
            'joy-order-tbk'
        ]:
            return 'www/{}-pre'.format(app)
        
    return 'www/{}'.format(app)
    
##获取代码的代码路径
def get_publish_code_path(app, is_intra = False):
    if is_intra is True:
        return '/alidata/www/{}/'.format(app)
    
    base_dir = CliTool.workspace()
    default_path = '{}.git'.format(app)
    
    return base_dir + default_path + '/'


##build下发布的排除文件    
def build_exclude_ext(ext_mode = None, exclude_atjmax = False):
    exclude_atjmax_exclude = ' --exclude=/api/app/libs/controller/atjmax/* --exclude=/api/app/views/page/atjmax/* '
    exclude_atjmax_exclude += ' --exclude=/app/libs/controller/atjmax/* --exclude=/app/views/page/atjmax/* '

    exclude_ext = ''
    if ext_mode == 'api':
        exclude_ext += ' --include=/api/ --exclude=/web/* '

    if ext_mode == 'web':
        exclude_ext += ' --exclude=/api/* --include=/web/dist/ '

    if exclude_atjmax is True:
        exclude_ext += exclude_atjmax_exclude

    return exclude_ext

#build发布命令
def build_command_tpl(del_type, pwd_file, exclude_ext, pubish_code_path):
    exclude_ext = CliTool.excludeFile() + exclude_ext
    cmd_tpl = 'rsync -%s --delay-updates {} --stats --port=%s --password-file={} --timeout=120 {} {} www@%s::%s/'.format(del_type, pwd_file, exclude_ext, pubish_code_path)
    return cmd_tpl

#发布sw机器的web部分
def pubish_sw(sw_hosts, code_type, mode_type, pwd_file, pubish_code_path):
    if code_type == 'api':
        return 
    
    if not sw_hosts:
        print("sw 机器为空")
        exit()
        
    exclude_ext_web =  build_exclude_ext(ext_mode='web')
    Ct = CliTool()
    cmd_tpl_web_no_del = build_command_tpl('', pwd_file, exclude_ext_web, pubish_code_path)
    print("\n\n正在发布[SW]机器 and no --del ...")
    Ct.publish(sw_hosts, mode_type, cmd_tpl_web_no_del)
    
    if code_type == 'web':
        cmd_tpl_web = build_command_tpl('--del', pwd_file, exclude_ext_web, pubish_code_path)
        print("\n\n正在发布[SW]机器")
        Ct.publish(sw_hosts, mode_type, cmd_tpl_web)
        
        
##开始发布
def start_publish(idc, app, mode, env, is_intra = False, code_type = None, is_web = False, force_port = None):
    """
    发布命令的开始入口
    
    args
    idc: str, 发布的idc机器
    app: str, 发布的app
    env : str, 发布的环境，根据host里面的hosts文件配置：real, pre, test, 等
    is_intra: bool, 是否是内网
    mode: str, 发布的模式可用为：real, rdtest, test
    is_web: bool, 是否是前后端分离项目
    code_type: str, 项目类型，可用为：api, web
    force_port: int, 强制指定端口
    """

    ##定义rsync基本命令
    pwd_file = '/home/porsche/publish/tjds1.passwd' if is_intra is True else '/Users/tangjianhui/Documents/publish/tjds1.passwd'
    pubish_code_path = get_publish_code_path(app, is_intra)
    Ct = CliTool()

    ##检查本地发布pub和real分支是否合法
    if (is_intra is False and env in ['pub', 'real']) and mode == 'real':
        realLocalSrc = pubish_code_path if os.path.exists(pubish_code_path + ".git") else pubish_code_path + 'api/'
        res = os.popen("cd " + realLocalSrc + " && git branch -a | grep '*' | awk '{print $2}'")
        branch = res.read().strip("\n")

        if any(keyword.lower() in branch.lower() for keyword in ['real', 'master', 'revert']) is False:
            print(("清检查分支: {} 是否为正式发布分支? 正式发布分支名称需包含 real、master、revert等关键词".format(branch)))
            exit()

    ##发布目标目录
    module = get_pubish_module(app, env)

    ##获取机器列表
    file_host_name_path = '{}/{}'.format(os.path.dirname(sys.argv[0]), get_idc_host_file(idc, app))

    if not os.path.exists(file_host_name_path):
        print("Host file {} does not exist.".format(file_host_name_path))
        return

    ##所有的机器列表
    ips_map = CliTool.getIpsMap(file_host_name_path, isIntra = is_intra, defaultPort = 8873, defaultModule = module, forePort=force_port)
    
    ##待发布的环境
    env_list = CliTool.getEnvList(env, ips_map, is_intra)

    ##获取发布的机器列表
    ips = {}
    for ev in env_list:
        if ev not in ips_map:
            continue
        ips = dict(ips, **ips_map[ev])

    ##其他正常发布(暂时手动控制白名单为主)
    exclude_atjmax = True 
    default_ext = build_exclude_ext(ext_mode=code_type, exclude_atjmax=exclude_atjmax)
    cmd_tpl_all = build_command_tpl('--del', pwd_file, default_ext, pubish_code_path)
    
    syntax_check = False if is_intra is True else True
    Ct.publish(ips, mode, cmd_tpl_all, is_intra, php_syntax_check = syntax_check)
   
def start_publish_zk(idc, zk, mode, env, is_intra = False, force_port = None):
    ##定义rsync基本命令
    pwd_file = '/home/porsche/publish/tjds2.passwd'
    
     ##获取机器列表
    file_host_name_path = '{}/{}'.format(os.path.dirname(sys.argv[0]), get_idc_host_file(idc=idc))
    if not os.path.exists(file_host_name_path):
        print("Host file {} does not exist.".format(file_host_name_path))
        return
    
    ips_map = CliTool.getIpsMap(file_host_name_path, isIntra = is_intra, defaultPort=8875, defaultModule = 's', forePort=force_port)
    
    ##待发布的环境
    env_list = CliTool.getEnvList(env, ips_map, is_intra)
    
    ##获取发布的机器列表
    ips = {}
    for env in env_list:
        ips = dict(ips, **ips_map[env])
        
    ##Zk文件
    if zk in ['xiuxiu-node-api', 'ai-ps', 'node-video-v2']:
        zkFile = 'Zk.' + zk  + '.json'
    else:
        zkFile = 'Zk.' + zk  + '.inc'
    
    pubish_code_path = '/alidata/s/' + zkFile
    cmdTpl = 'rsync -%s --delay-updates --del --stats --port=%s --password-file=' + pwd_file + ' --timeout=30 ' + pubish_code_path + ' root@%s::%s/' + zkFile
    Ct = CliTool()
    Ct.publish(ips, mode, cmdTpl)

if __name__ == '__main__':
    pass