#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Cloud Raiser · 浙江省选拔赛 - 云计算项目 - 架构完善模块 - 阶段1 Restful API
=========================================================================
端点：
    POST /post_data1         把 {id,value} 写入 DynamoDB（表 cr-data1）
    POST /post_data2         把 {id,value} 写入 Aurora MySQL（表 data2）
    GET  /get_value?id=01    从两库按 id 查 value，求和后返回 {"message":"579"}
    GET  /healthz            健康检查

部署方式：Gunicorn + Nginx（端口 80 反向代理到 5000；Web 应用 8082）
"""
import os
import json
import logging
from flask import Flask, request, jsonify
import boto3
import pymysql
from botocore.config import Config

# ---------------- 日志 ----------------
logging.basicConfig(
    level=logging.INFO,
    format="%(asctime)s %(levelname)s %(name)s: %(message)s",
    handlers=[
        logging.StreamHandler(),
        logging.FileHandler("/var/log/cr-api.log", encoding="utf-8"),
    ],
)
log = logging.getLogger("cr-api")

app = Flask(__name__)

# ---------------- DynamoDB ----------------
DDB_TABLE = os.environ.get("DDB_TABLE", "cr-data1")
AWS_REGION = os.environ.get("AWS_REGION", "cn-northwest-1")
ddb = boto3.resource(
    "dynamodb",
    region_name=AWS_REGION,
    config=Config(retries={"max_attempts": 3, "mode": "standard"}),
)
table_ddb = ddb.Table(DDB_TABLE)

# ---------------- Aurora MySQL ----------------
DB_HOST = os.environ["DB_HOST"]
DB_USER = os.environ.get("DB_USER", "admin")
DB_PASS = os.environ["DB_PASS"]
DB_NAME = os.environ.get("DB_NAME", "crdb")


def db_conn():
    return pymysql.connect(
        host=DB_HOST,
        user=DB_USER,
        password=DB_PASS,
        database=DB_NAME,
        charset="utf8mb4",
        connect_timeout=5,
        read_timeout=10,
        write_timeout=10,
    )


def _ensure_db_and_table():
    """首次启动时自动创建 database 和 data2 表（建库阶段没建也能自愈）"""
    # 1) 先连 MySQL server（不带 database）建库
    cn = pymysql.connect(
        host=DB_HOST,
        user=DB_USER,
        password=DB_PASS,
        charset="utf8mb4",
        connect_timeout=5,
        read_timeout=10,
        write_timeout=10,
    )
    try:
        with cn.cursor() as c:
            c.execute(f"CREATE DATABASE IF NOT EXISTS {DB_NAME} CHARACTER SET utf8mb4")
        cn.commit()
    finally:
        cn.close()

    # 2) 再连目标库建表
    cn = db_conn()
    try:
        with cn.cursor() as c:
            c.execute(
                """CREATE TABLE IF NOT EXISTS data2 (
                    id   VARCHAR(64)  PRIMARY KEY,
                    value VARCHAR(255) NOT NULL
                ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4"""
            )
        cn.commit()
    finally:
        cn.close()


# 启动时建库建表
try:
    _ensure_db_and_table()
    log.info("data2 table ensured")
except Exception as e:  # pragma: no cover
    log.warning("ensure_table failed: %s", e)


# ---------------- 路由 ----------------
@app.route("/healthz", methods=["GET"])
def healthz():
    return jsonify(ok=True)


@app.route("/post_data1", methods=["POST"])
def post_data1():
    body = request.get_json(force=True, silent=True) or {}
    _id = str(body.get("id", "")).strip()
    val = body.get("value", "")
    if not _id:
        return jsonify(message="id required"), 400
    table_ddb.put_item(Item={"id": _id, "value": str(val)})
    log.info("DDB PUT id=%s val=%s", _id, val)
    return jsonify(message="ok")


@app.route("/post_data2", methods=["POST"])
def post_data2():
    body = request.get_json(force=True, silent=True) or {}
    _id = str(body.get("id", "")).strip()
    val = body.get("value", "")
    if not _id:
        return jsonify(message="id required"), 400
    cn = db_conn()
    try:
        with cn.cursor() as c:
            c.execute(
                """INSERT INTO data2 (id, value) VALUES (%s, %s)
                   ON DUPLICATE KEY UPDATE value=VALUES(value)""",
                (_id, val),
            )
        cn.commit()
    finally:
        cn.close()
    log.info("RDS PUT id=%s val=%s", _id, val)
    return jsonify(message="ok")


@app.route("/get_value", methods=["GET"])
def get_value():
    _id = str(request.args.get("id", "")).strip()
    if not _id:
        return jsonify(message="id required"), 400

    ddb_val = (
        table_ddb.get_item(Key={"id": _id})
        .get("Item", {})
        .get("value", "0")
    )

    rds_val = "0"
    cn = db_conn()
    try:
        with cn.cursor() as c:
            c.execute("SELECT value FROM data2 WHERE id=%s", (_id,))
            row = c.fetchone()
            if row:
                rds_val = row[0]
    finally:
        cn.close()

    try:
        total = int(ddb_val) + int(rds_val)
    except (TypeError, ValueError):
        total = f"{ddb_val}{rds_val}"
    log.info("GET id=%s ddb=%s rds=%s total=%s", _id, ddb_val, rds_val, total)
    return jsonify(message=str(total))


# ---------------- 入口 ----------------
if __name__ == "__main__":
    # 直接 python3 跑也支持；生产由 gunicorn 启动
    app.run(host="127.0.0.1", port=5000)
