# -*- coding:utf-8 -*-
import argparse
import json
from http.server import BaseHTTPRequestHandler, ThreadingHTTPServer
from urllib.parse import urlparse

from base_framework.platform_tools.Create_ui_testcase.generate_automation_api import (
    generate_save_and_verify_ui_testcase
)


API_PATH = "/it/api/case/generate-automation"


class GenerateAutomationHandler(BaseHTTPRequestHandler):

    def do_OPTIONS(self):
        self._send_json_response(200, {"code": 0, "message": "ok", "data": None})

    def do_POST(self):
        request_path = urlparse(self.path).path
        if request_path != API_PATH:
            self._send_json_response(404, {
                "code": 404,
                "message": "接口不存在：{0}".format(request_path),
                "data": None
            })
            return

        try:
            request_data = self._read_json_body()
            self._validate_required_fields(request_data)

            if request_data.get("automationType") != "ui":
                self._send_json_response(200, {
                    "code": 1,
                    "message": "automationType不是ui，不调用UI自动化用例生成接口",
                    "data": {
                        "projectId": request_data.get("projectId"),
                        "caseId": request_data.get("caseId"),
                        "automationType": request_data.get("automationType"),
                        "caseKey": request_data.get("caseKey"),
                        "content": self._get_case_name(request_data)
                    }
                })
                return

            generation_mode = self._get_generation_mode(request_data)
            normalized_prompt = self._build_effective_prompt(request_data)
            normalized_steps = self._normalize_text_list(request_data.get("steps"))
            normalized_expected_results = self._normalize_text_list(request_data.get("expectedResults"))
            max_attempts = self._get_max_attempts(request_data, generation_mode)

            verify_result = generate_save_and_verify_ui_testcase(
                project_id=request_data.get("projectId"),
                case_id=request_data.get("caseId"),
                automation_type=request_data.get("automationType"),
                prompt=normalized_prompt,
                case_key=request_data.get("caseKey"),
                module_name=request_data.get("moduleName"),
                product_name=request_data.get("productName"),
                project_name=request_data.get("projectName"),
                steps=normalized_steps,
                expected_results=normalized_expected_results,
                case_name=self._get_case_name(request_data),
                enable_reconnaissance=self._should_enable_reconnaissance(request_data, generation_mode),
                headless=request_data.get("headless", True),
                max_attempts=max_attempts
            )

            response_data = self._build_response_data(request_data, verify_result, generation_mode)
            if not verify_result.get("success"):
                self._send_json_response(200, {
                    "code": self._build_failure_code(verify_result),
                    "message": verify_result.get("verificationMessage") or "用例生成后执行失败，自动修复{0}次仍未通过".format(max_attempts),
                    "data": response_data
                })
                return

            self._send_json_response(200, {
                "code": 0,
                "message": verify_result.get("verificationMessage") or "success",
                "data": response_data
            })
        except ValueError as error:
            self._send_json_response(400, {
                "code": 400,
                "message": str(error),
                "data": None
            })
        except Exception as error:
            self._send_json_response(500, {
                "code": 500,
                "message": self._sanitize_error_message(str(error)),
                "data": None
            })

    def _read_json_body(self):
        content_length = int(self.headers.get("Content-Length", 0))
        if content_length <= 0:
            raise ValueError("请求体不能为空")

        body = self.rfile.read(content_length).decode("utf-8")
        try:
            return json.loads(body)
        except ValueError:
            raise ValueError("请求体必须是合法JSON")

    def _validate_required_fields(self, request_data):
        required_fields = [
            "projectId",
            "caseId",
            "automationType",
            "prompt",
            "caseKey",
            "moduleName",
            "productName",
            "projectName",
            "steps",
            "expectedResults"
        ]
        missing_fields = []
        for field in required_fields:
            if field == "productName":
                if field not in request_data or request_data.get(field) is None:
                    missing_fields.append(field)
            elif request_data.get(field) in (None, ""):
                missing_fields.append(field)
        if missing_fields:
            raise ValueError("缺少必填参数：{0}".format(", ".join(missing_fields)))

    def _get_case_name(self, request_data):
        return request_data.get("caseName") or request_data.get("title") or request_data.get("name") or "{0}-{1}".format(
            request_data.get("caseKey"),
            request_data.get("moduleName")
        )

    def _normalize_text_list(self, value):
        if isinstance(value, list):
            return "\n".join(str(item) for item in value)
        return str(value or "")

    def _get_generation_mode(self, request_data):
        generation_mode = str(request_data.get("generationMode") or "fast").strip().lower()
        if generation_mode not in ("fast", "recon"):
            raise ValueError("generationMode仅支持fast或recon")
        return generation_mode

    def _should_enable_reconnaissance(self, request_data, generation_mode):
        if "enableReconnaissance" in request_data:
            return bool(request_data.get("enableReconnaissance"))
        return generation_mode == "recon"

    def _get_max_attempts(self, request_data, generation_mode):
        default_attempts = 1 if generation_mode == "fast" else 2
        try:
            max_attempts = int(request_data.get("maxAttempts", default_attempts))
        except (TypeError, ValueError):
            raise ValueError("maxAttempts必须是整数")
        return max(1, min(max_attempts, 3))

    def _build_effective_prompt(self, request_data):
        prompt_parts = [self._normalize_text_list(request_data.get("prompt"))]
        selectors = request_data.get("selectors")
        test_data = request_data.get("testData")
        if isinstance(selectors, dict) and selectors:
            prompt_parts.append("前端传入的页面元素 selectors：\n{0}".format(json.dumps(selectors, ensure_ascii=False, indent=2)))
        if isinstance(test_data, dict) and test_data:
            prompt_parts.append("前端传入的测试数据 testData：\n{0}".format(json.dumps(test_data, ensure_ascii=False, indent=2)))
        return "\n\n".join(part for part in prompt_parts if part)

    def _build_response_data(self, request_data, verify_result, generation_mode):
        return {
            "projectId": request_data.get("projectId"),
            "caseId": request_data.get("caseId"),
            "automationType": request_data.get("automationType"),
            "caseKey": request_data.get("caseKey"),
            "content": self._get_case_name(request_data),
            "generationMode": generation_mode,
            "testcasePath": verify_result.get("testcasePath"),
            "attempts": verify_result.get("attempts"),
            "quality": verify_result.get("quality"),
            "verificationStatus": verify_result.get("verificationStatus"),
            "verificationMessage": verify_result.get("verificationMessage"),
            "failureReason": verify_result.get("failureReason")
        }

    def _build_failure_code(self, verify_result):
        verification_status = verify_result.get("verificationStatus")
        if verification_status == "skipped":
            return 3002
        if verification_status == "timeout":
            return 3004
        return 3001

    def _sanitize_error_message(self, message):
        return str(message or "").replace("password", "******").replace("密码", "密码******")

    def _send_json_response(self, status_code, response_data):
        response_body = json.dumps(response_data, ensure_ascii=False).encode("utf-8")
        self.send_response(status_code)
        self.send_header("Content-Type", "application/json;charset=UTF-8")
        self.send_header("Access-Control-Allow-Origin", "*")
        self.send_header("Access-Control-Allow-Methods", "POST, OPTIONS")
        self.send_header("Access-Control-Allow-Headers", "Content-Type, accessToken, Authorization")
        self.send_header("Content-Length", str(len(response_body)))
        self.end_headers()
        self.wfile.write(response_body)

    def log_message(self, format, *args):
        print("[{0}] {1}".format(self.log_date_time_string(), format % args))


def run_server(host="0.0.0.0", port=8081):
    server = ThreadingHTTPServer((host, port), GenerateAutomationHandler)
    print("Create_ui_testcase HTTP服务已启动：http://{0}:{1}".format(host, port))
    print("接口地址：POST {0}".format(API_PATH))
    server.serve_forever()


if __name__ == "__main__":
    parser = argparse.ArgumentParser(description="UI自动化用例生成HTTP服务")
    parser.add_argument("--host", default="0.0.0.0", help="服务监听地址，默认0.0.0.0")
    parser.add_argument("--port", default=8081, type=int, help="服务监听端口，默认8081")
    args = parser.parse_args()
    run_server(host=args.host, port=args.port)
