package com.huangzj.protoplugin;

import java.util.ArrayList;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * 轻量解析 proto3：提取 {@code option java_package}、{@code service} 块内的 {@code rpc ... (Req) returns (Res)}。
 */
public final class ProtoFileParser {

    private static final Pattern JAVA_PACKAGE =
            Pattern.compile("option\\s+java_package\\s*=\\s*\"([^\"]+)\"\\s*;", Pattern.MULTILINE);
    private static final Pattern SERVICE_HEADER =
            Pattern.compile("\\bservice\\s+(\\w+)\\s*\\{");
    private static final Pattern RPC_LINE = Pattern.compile(
            "\\brpc\\s+(\\w+)\\s*\\(\\s*(\\w+)\\s*\\)\\s*returns\\s*\\(\\s*(\\w+)\\s*\\)\\s*;",
            Pattern.MULTILINE);

    private ProtoFileParser() {}

    public static ProtoParseResult parse(String content) {
        String javaPkg = null;
        Matcher jm = JAVA_PACKAGE.matcher(content);
        if (jm.find()) {
            javaPkg = jm.group(1);
        }

        List<RpcMethodInfo> out = new ArrayList<>();
        Matcher sm = SERVICE_HEADER.matcher(content);
        while (sm.find()) {
            String serviceName = sm.group(1);
            Integer idx = parseServiceIndex(serviceName);
            if (idx == null) {
                continue;
            }
            int blockStart = sm.end() - 1;
            int blockEnd = findMatchingBrace(content, blockStart);
            if (blockEnd < 0) {
                continue;
            }
            String block = content.substring(blockStart + 1, blockEnd);
            Matcher rm = RPC_LINE.matcher(block);
            int rpcIndex = 0;
            while (rm.find()) {
                String rpcName = rm.group(1);
                String req = rm.group(2);
                String res = rm.group(3);
                out.add(new RpcMethodInfo(serviceName, idx, rpcIndex, rpcName, req, res));
                rpcIndex++;
            }
        }
        return new ProtoParseResult(javaPkg, out);
    }

    /** 识别 {@code Service1Service} → 1；其它命名返回 null 并跳过该 service。 */
    static Integer parseServiceIndex(String serviceName) {
        Matcher m = Pattern.compile("^Service(\\d+)Service$").matcher(serviceName);
        if (m.matches()) {
            return Integer.parseInt(m.group(1));
        }
        return null;
    }

    static int findMatchingBrace(String s, int openBraceIndex) {
        int depth = 0;
        for (int i = openBraceIndex; i < s.length(); i++) {
            char c = s.charAt(i);
            if (c == '{') {
                depth++;
            } else if (c == '}') {
                depth--;
                if (depth == 0) {
                    return i;
                }
            }
        }
        return -1;
    }
}
