#coding utf8
#!/usr/bin/python

import os
import sys
import time
import threading
import subprocess
from optparse import OptionParser

g_is_terminated = False
def is_terminated():
    return g_is_terminated

def printp_stdout(p):
    try:
        while not is_terminated():
            line = p.stdout.readline()
            if len(line) > 0:
                print(line, end = '')
    except Exception as e:
        print('build_pb stdout error:' + e)

def printp_stderr(p):
    try:
        while is_terminated():
            line = p.stderr.readline()
            if len(line) > 0:
                print(line, end = '')
    except Exception as e:
        print('build_pb stderr error:' + e)

def rebuild_impb():
    #pb_files = ['im_proto', 'im_msgid']
    pb_files = []
    cpp_out = '../../third_party/framework/cpp/'
    for proto_name in pb_files:
        pb_file = proto_name
        pb_dir = '../../third_party/framework/cpp/'
        if not os.path.isfile(pb_dir + proto_name + '.pb.cc'):
            cmd = 'protoc --proto_path=../../third_party/framework/cpp --cpp_out=%s ../../third_party/framework/cpp/%s.proto ' % (cpp_out, pb_file)
            print(cmd)
            os.system(cmd)
            continue
        s1 = os.stat(pb_dir + proto_name + '.pb.cc')
        s2 = os.stat(pb_dir + proto_name + '.proto')
        if s1.st_size <= 0 or s1.st_mtime < s2.st_mtime:
            cmd = 'protoc --proto_path=../../third_party/framework/cpp --cpp_out=%s ../../third_party/framework/cpp/%s.proto ' % (cpp_out, pb_file)
            print(cmd )
            os.system(cmd)

def need_rebuild(pb_files):
    for proto_name in pb_files:
        if not os.path.isfile(proto_name + '.pb.cc'):
            return True
        s1 = os.stat(proto_name + '.pb.cc')
        s2 = os.stat('../tools/protobuild/' + proto_name + '.proto')
        if s1.st_size <= 0 or s1.st_mtime < s2.st_mtime:
            return True
    return False

def rebuild(cpp_out, python_out, java_out, pb_files):
    def genParams():
        cpp_param = ''
        py_param = ''
        java_param = ''
        for pb_file in pb_files:
            if cpp_out != '':
                cpp_param += 'protoc --proto_path=../tools/protobuild --cpp_out=%s ../tools/protobuild/%s.proto && ' % (cpp_out, pb_file)
            if python_out != '':
                py_param += '../../third_party/tools/bin/protoc --proto_path=../tools/protobuild --python_out=%s ../tools/protobuild/%s.proto && ' % (python_out, pb_file)
            if java_out != '':
                py_param += '../../third_party/tools/bin/protoc --proto_path=../tools/protobuild --java_out=%s ../tools/protobuild/%s.proto && ' % (java_out, pb_file)
        return cpp_param + py_param + java_param + ' echo ""'
    global g_is_terminated
    try:
#        print(genParams())
        p = subprocess.Popen(
            genParams(),
            stdin = subprocess.PIPE,
            stdout = subprocess.PIPE,
            stderr = None,
            shell = True)
        t1 = threading.Thread(target = printp_stdout, args=(p, ))
        t2 = threading.Thread(target = printp_stderr, args=(p, ))
        t1.start()
        t2.start()
        p.wait()
        g_is_terminated = True
        t1.join()
        t2.join()
        sys.exit(p.returncode)
    except Exception as e:
        print('build_protocol rebuild error:' + str(e))

def repair_githooks():
    os.system('/bin/bash ../../third_party/tools/scripts/githooks/install.sh')

parser = OptionParser(usage="%prog [options]")
parser.add_option(
    "-n",
    "--nohooks",
    dest = "nohooks",
    help = "no repair git hooks",
)
parser.add_option(
    "",
    "--cpp_out",
    dest = "cpp_out",
    default = '',
    help = "",
)
parser.add_option(
    "",
    "--python_out",
    dest = "python_out",
    default = '',
    help = "",
)
parser.add_option(
    "",
    "--java_out",
    dest = "java_out",
    default = '',
    help = "",
)
parser.add_option(
    "",
    "--pb_files",
    dest = "pb_files",
    help = "",
)
(options, args) = parser.parse_args()
#if not options.nohooks:
#    repair_githooks()

rebuild_impb()
if need_rebuild(options.pb_files.split(',')):
    rebuild(options.cpp_out, options.python_out, options.java_out, options.pb_files.split(','))
else:
    print('pb files already is the latest')
