# -*- coding: utf-8 -*-
from __future__ import print_function
import os
import io
import threading
import webbrowser
import os
import subprocess
import signal
import sys
import locale


PORT = 9998  # 静态文件服务端口
API_PORT = 23456  # 接收 POST 请求服务端口

try:
    # Python 3
    from http.server import SimpleHTTPRequestHandler, BaseHTTPRequestHandler, HTTPServer
    from urllib.parse import unquote, urlparse, parse_qs
    import socketserver
    PY3 = True
except ImportError:
    # Python 2
    from SimpleHTTPServer import SimpleHTTPRequestHandler
    from BaseHTTPServer import BaseHTTPRequestHandler, HTTPServer
    from urlparse import urlparse, parse_qs
    from urllib import unquote
    import SocketServer as socketserver
    PY3 = False


# 构建 js/htmlfiles.js，包含当前目录下所有 html 文件列表
def generate_html_files_js():
    html_files = []
    for f in os.listdir('.'):
        if f.lower().endswith('.html') and f.lower() != 'index.html':
            html_files.append("'{}'".format(f))
    js_content = "let html_files = [{}];".format(', '.join(html_files))
    js_dir = 'js'
    if not os.path.exists(js_dir):
        os.makedirs(js_dir)
    with io.open(os.path.join(js_dir, 'htmlfiles.js'), 'w', encoding='utf-8') as f:
        f.write(js_content)


# 静态文件服务
def start_simple_server():
    handler = SimpleHTTPRequestHandler
    httpd = socketserver.TCPServer(("localhost", PORT), handler)
    print("Serving static files on http://localhost:%d/" % PORT)
    webbrowser.open("http://localhost:%d/index.html" % PORT)
    httpd.serve_forever()


# 接收 POST 请求写文件的服务
class RequestHandler(BaseHTTPRequestHandler):
    def _set_headers(self, content_length):
        self.send_response(200)
        self.send_header('Content-type', 'text/plain; charset=utf-8')
        self.send_header('Access-Control-Allow-Origin', '*')
        self.send_header('Access-Control-Allow-Methods', 'GET, POST, OPTIONS')
        self.send_header('Access-Control-Allow-Headers', 'Content-Type')
        self.send_header('Content-Length', str(content_length))
        self.end_headers()

    def do_OPTIONS(self):
        self.send_response(204)
        self.send_header('Access-Control-Allow-Origin', '*')
        self.send_header('Access-Control-Allow-Methods', 'GET, POST, OPTIONS')
        self.send_header('Access-Control-Allow-Headers', 'Content-Type')
        self.send_header('Content-Length', '0')
        self.end_headers()

    def do_GET(self):
        message = u"This is a POST-only server. Use POST with ?file=yourpath"
        encoded = message.encode('utf-8')
        self._set_headers(len(encoded))
        self.wfile.write(encoded)

    def do_POST(self):
        length = int(self.headers.get('Content-Length', 0))
        body = self.rfile.read(length)
        if isinstance(body, bytes):
            body = body.decode('utf-8')

        parsed_url = urlparse(self.path)
        query = parse_qs(parsed_url.query)
        filepath = query.get('file', [''])[0]

        if filepath:
            filepath = unquote(filepath)
            try:
                with io.open(filepath, 'w', encoding='utf-8') as f:
                    f.write(body)
            except Exception as e:
                self.send_error(500, str(e))
                return

        response = u'true'
        encoded = response.encode('utf-8')
        self._set_headers(len(encoded))
        self.wfile.write(encoded)


def start_api_server():
    server_address = ('localhost', API_PORT)
    httpd = HTTPServer(server_address, RequestHandler)
    print('Serving API on http://localhost:%d/' % API_PORT)
    httpd.serve_forever()


def print_utf8(s):
    # 兼容py2和py3的print，避免编码问题
    if sys.version_info[0] < 3:
        # python2: 输出时先编码为utf-8
        print(s.encode('utf-8'))
    else:
        print(s)

def kill_process(process_name):
    try:
        # /F 强制结束, /IM 按名称, /T 结束子进程
        subprocess.check_call(['taskkill', '/F', '/IM', process_name, '/T'])
        print_utf8(u"已终止进程：{}".format(process_name))
    except subprocess.CalledProcessError:
        print_utf8(u"未找到或无法终止进程：{}".format(process_name))

def killcmd():
    print_utf8(u"正在终止所有 cmd.exe 和 powershell.exe 进程...")

    # 结束进程列表
    processes = ['pwsh.exe', 'powershell.exe', 'cmd.exe']
    for p in processes:
        kill_process(p)

    print_utf8(u"操作完成。")


def kill_process_on_port(port):
    try:
        if os.name == 'nt':
            import locale
            encoding = locale.getpreferredencoding()
            cmd_find = ['netstat', '-ano']
            output = subprocess.check_output(cmd_find)
            output = output.decode(encoding, errors='ignore')
            for line in output.splitlines():
                if 'LISTENING' in line and ':%d' % port in line:
                    parts = line.strip().split()
                    if len(parts) >= 5:
                        pid = int(parts[-1])
                        print("Killing process on port %d with PID %d (Windows)" % (port, pid))
                        subprocess.call(['taskkill', '/PID', str(pid), '/F'])
                    return
        else:
            cmd = "lsof -i :%d -t" % port
            output = subprocess.check_output(cmd, shell=True)
            output = output.decode('utf-8', errors='ignore').strip()
            if output:
                for pid in output.splitlines():
                    print("Killing process on port %d with PID %s" % (port, pid))
                    os.kill(int(pid), signal.SIGKILL)
    except Exception as e:
        print("No need to kill port %d: %s" % (port, e))
        if os.name == 'nt':
            killcmd()

if __name__ == '__main__':
    kill_process_on_port(PORT)
    kill_process_on_port(API_PORT)
    os.chdir(os.path.dirname(os.path.abspath(__file__)))  # 切换到脚本目录
    generate_html_files_js()

    # 启动两个线程
    t1 = threading.Thread(target=start_simple_server)
    t2 = threading.Thread(target=start_api_server)

    t1.daemon = True
    t2.daemon = True

    t1.start()
    t2.start()

    # 保持主线程运行
    t1.join()
    t2.join()
