import logging
import sys
import hashlib
import random
import pymysql
from flask import Flask, request, jsonify
from gevent import pywsgi
from contextlib import contextmanager

# ---------------- 日志配置 ----------------
logging.basicConfig(
    level=logging.INFO,
    format="%(asctime)s [%(levelname)s] %(message)s",
    handlers=[logging.StreamHandler(sys.stdout)]
)
logger = logging.getLogger(__name__)

# ---------------- Flask 应用 ----------------
app = Flask(__name__)

# ---------------- 数据库连接 ----------------
@contextmanager
def db_conn():
    conn = pymysql.connect(
        host="localhost",
        port=3306,
        user="root",
        passwd="7758258753",
        database="db3",
        autocommit=True,
        charset="utf8mb4"
    )
    cursor = conn.cursor()
    try:
        yield conn, cursor
    finally:
        cursor.close()
        conn.close()

# ---------------- 工具函数 ----------------
def success(data=None):
    return jsonify({"status": "success", "data": data})

def failed(error_msg):
    return jsonify({"status": "failed", "error": error_msg})

# ---------------- 业务逻辑 ----------------
def add_machine(machineID, key):
    with db_conn() as (conn, cursor):
        cursor.execute("SELECT 1 FROM gms_id_data WHERE machineID=%s", (machineID,))
        if cursor.fetchone():
            return f"machineID:{machineID} 已存在"
        cursor.execute("SELECT DATE_ADD(CURRENT_TIMESTAMP, INTERVAL 7 DAY)")
        expire_time = cursor.fetchone()[0]
        cursor.execute(
            "INSERT INTO gms_id_data (machineID, license_key, expire_time) VALUES (%s, %s, %s)",
            (machineID, key, expire_time)
        )
        return f"成功添加 machineID={machineID}, 到期时间={expire_time}"

def insert_order(machineID, order_no):
    with db_conn() as (conn, cursor):
        cursor.execute("SELECT 1 FROM gms_id_data WHERE machineID=%s", (machineID,))
        if not cursor.fetchone():
            return f"machineID:{machineID} 不存在"

        cursor.execute("SELECT 1 FROM gms_id_data WHERE order_no=%s", (order_no,))
        if cursor.fetchone():
            return f"order_no:{order_no} 已存在"

        cursor.execute(
            "SELECT register_time, expire_time FROM gms_id_data WHERE machineID=%s ORDER BY register_time DESC LIMIT 1",
            (machineID,)
        )
        row = cursor.fetchone()
        if not row:
            return f"machineID:{machineID} 没有历史记录"

        rt, et = row
        cursor.execute("SELECT CURRENT_TIMESTAMP")
        ct = cursor.fetchone()[0]

        if ct > et:
            cursor.execute("SELECT DATE_ADD(%s, INTERVAL 1 YEAR)", (ct,))
        else:
            cursor.execute("SELECT DATE_ADD(%s, INTERVAL 1 YEAR)", (et,))
        new_expire_time = cursor.fetchone()[0]

        cursor.execute(
            "INSERT INTO gms_id_data (machineID, license_key, order_no, register_time, expire_time) VALUES (%s, %s, %s, %s, %s)",
            (machineID, "", order_no, ct, new_expire_time)
        )
        return f"成功插入 machineID={machineID}, order_no={order_no}, 到期时间={new_expire_time}"

# ---------------- API 路由 ----------------
@app.route("/generator", methods=["GET", "POST"])
def gen():
    machineID = request.args.get("machineID") or request.form.get("machineID")
    if not machineID:
        return failed("missing machineID")

    with db_conn() as (conn, cursor):
        cursor.execute("SELECT 1 FROM gms_id_data WHERE machineID=%s", (machineID,))
        if cursor.fetchone():
            return failed("already exists")

        rint = random.randint(100000000000000, 999999999999999)
        md5 = hashlib.md5(str(rint).encode()).hexdigest()[:16].upper()
        msg = add_machine(machineID, md5)
        logger.info(msg)
        return success({"license_key": md5})

@app.route("/verify", methods=["GET", "POST"])
def verify():
    machineID = request.args.get("machineID") or request.form.get("machineID")
    key = request.args.get("license_key") or request.form.get("license_key")
    if not machineID or not key:
        return failed("missing parameters")

    with db_conn() as (conn, cursor):
        cursor.execute("SELECT 1 FROM gms_id_data WHERE machineID=%s AND license_key=%s", (machineID, key))
        return success() if cursor.fetchone() else failed("验证失败")

@app.route("/getorder", methods=["GET", "POST"])
def get_order_no():
    machineID = request.args.get("machineID") or request.form.get("machineID")
    if not machineID:
        return failed("missing machineID")

    with db_conn() as (conn, cursor):
        cursor.execute("SELECT order_no FROM gms_id_data WHERE machineID=%s ORDER BY expire_time DESC LIMIT 1", (machineID,))
        row = cursor.fetchone()
        if row and row[0]:
            return success({"order_no": row[0]})
        return failed("no matching record")

@app.route("/order", methods=["GET", "POST"])
def verify_order():
    order_no = request.args.get("order_no") or request.form.get("order_no")
    if not order_no:
        return failed("missing order_no")

    if "_" in order_no:
        order_no = order_no.split("_")[1]

    if len(order_no) < 5:
        return failed("order_no too short")

    with db_conn() as (conn, cursor):
        cursor.execute("SELECT 1 FROM gms_id_data WHERE order_no LIKE %s", ("%" + order_no + "%",))
        return success() if cursor.fetchone() else failed("not found")

@app.route("/update", methods=["GET", "POST"])
def new_order():
    machineID = request.args.get("machineID") or request.form.get("machineID")
    order_no = request.args.get("order_no") or request.form.get("order_no")
    if not machineID or not order_no:
        return failed("missing parameters")

    if "_" in order_no:
        order_no = order_no.split("_")[1]

    msg = insert_order(machineID, order_no)
    logger.info(msg)
    return success({"message": msg})

@app.route("/time", methods=["GET", "POST"])
def verify_time():
    machineID = request.args.get("machineID") or request.form.get("machineID")
    if not machineID:
        return failed("missing machineID")

    with db_conn() as (conn, cursor):
        cursor.execute("SELECT expire_time FROM gms_id_data WHERE machineID=%s ORDER BY expire_time DESC LIMIT 1", (machineID,))
        row = cursor.fetchone()
        if not row:
            return failed("no record")

        et = row[0]
        cursor.execute("SELECT CURRENT_TIMESTAMP")
        ct = cursor.fetchone()[0]

        if ct > et:
            return failed(f"expired at {et}")
        return success({"future_time": et})

# ---------------- 主入口 ----------------
if __name__ == "__main__":
    logger.info("Starting GMS server on 0.0.0.0:5001")
    server = pywsgi.WSGIServer(('0.0.0.0', 5001), app, log=logger, error_log=logger)
    server.serve_forever()

