import json


FILE = "./openapi.json"
with open(FILE, "r") as f:
    data = json.load(f)
    for path in data["paths"]:
        methods = list(data["paths"][path].keys())
        has_multiple_methods = len(methods) > 1

        for method in methods:
            if "api/v1/" in path:
                base_name = path.split("api/v1/")[1].replace("/", "_")
                data["paths"][path][method]["summary"] = base_name
                if has_multiple_methods:
                    data["paths"][path][method]["operationId"] = f"{base_name}_{method}"
                else:
                    data["paths"][path][method]["operationId"] = base_name
            elif "api/v2/" in path:
                base_name = path.split("api/v2/")[1].replace("/", "_") + "_v2"
                data["paths"][path][method]["summary"] = base_name
                if has_multiple_methods:
                    data["paths"][path][method]["operationId"] = f"{base_name}_{method}"
                else:
                    data["paths"][path][method]["operationId"] = base_name
            else:
                base_name = path.split("/")[-1]
                data["paths"][path][method]["summary"] = base_name
                if has_multiple_methods:
                    data["paths"][path][method]["operationId"] = f"{base_name}_{method}"
                else:
                    data["paths"][path][method]["operationId"] = base_name

            if data["paths"][path][method]["summary"] == "":
                data["paths"][path][method]["summary"] = "status"
                if has_multiple_methods:
                    data["paths"][path][method]["operationId"] = f"status_{method}"
                else:
                    data["paths"][path][method]["operationId"] = "status"

    # Replace $ref to int16 with inline int64 in RespGetMakerOnlyApiKeys.
    # int16 is not a standard OpenAPI format and causes the generator to emit
    # broken Int16 model references when used as a $ref in response schemas.
    def replace_int16_refs(obj):
        if isinstance(obj, dict):
            if obj.get("$ref") == "#/definitions/int16":
                return {"type": "integer", "format": "int64"}
            return {k: replace_int16_refs(v) for k, v in obj.items()}
        if isinstance(obj, list):
            return [replace_int16_refs(i) for i in obj]
        return obj

    if "RespGetMakerOnlyApiKeys" in data["definitions"]:
        data["definitions"]["RespGetMakerOnlyApiKeys"] = replace_int16_refs(
            data["definitions"]["RespGetMakerOnlyApiKeys"]
        )

    # Fix enum placement for array types: move enum from array level into items
    for defn in data["definitions"].values():
        for prop in defn.get("properties", {}).values():
            if prop.get("type") == "array" and "enum" in prop:
                prop["items"]["enum"] = prop.pop("enum")

    # transfer_history type parameter to be array
    if "/api/v1/transfer/history" in data["paths"]:
        for method in data["paths"]["/api/v1/transfer/history"].values():
            for param in method.get("parameters", []):
                if (
                    param.get("name") == "type"
                    and param.get("type") == "string"
                    and "enum" in param
                ):
                    param["type"] = "array"
                    param["items"] = {"type": "string", "enum": param.pop("enum")}
                    break

    for path in data["definitions"]:
        if not path.startswith("Req"):
            required_fields = list(data["definitions"][path]["properties"].keys())
            if "message" in required_fields:
                required_fields.remove("message")

            if "next" in required_fields:
                required_fields.remove("next")

            if "next_cursor" in required_fields:
                required_fields.remove("next_cursor")

            if "account_share" in required_fields:
                required_fields.remove("account_share")

            if "total_funding_paid_out" in required_fields:
                required_fields.remove("total_funding_paid_out")

            if "pending_unlocks" in required_fields:
                required_fields.remove("pending_unlocks")

            if "account_trading_mode" in required_fields:
                required_fields.remove("account_trading_mode")

            if "funding_fee_discounts_enabled" in required_fields:
                required_fields.remove("funding_fee_discounts_enabled")

            if "hidden" in required_fields:
                required_fields.remove("hidden")

            if "approved_integrators" in required_fields:
                required_fields.remove("approved_integrators")

            if "ask_id_str" in required_fields:
                required_fields.remove("ask_id_str")

            if "bid_id_str" in required_fields:
                required_fields.remove("bid_id_str")

            if path == "Trade":
                if "taker_fee" in required_fields:
                    required_fields.remove("taker_fee")

                if "maker_fee" in required_fields:
                    required_fields.remove("maker_fee")

            if len(required_fields) > 0:
                data["definitions"][path]["required"] = required_fields
            else:
                data["definitions"][path].pop("required", None)

with open(FILE, "w") as f:
    json.dump(data, f, indent=2)
