package com.codechecker.api.parser;

import com.github.javaparser.ast.body.MethodDeclaration;
import com.github.javaparser.ast.comments.JavadocComment;
import com.github.javaparser.ast.expr.AnnotationExpr;
import com.github.javaparser.ast.expr.Expression;
import com.github.javaparser.ast.expr.NormalAnnotationExpr;
import com.github.javaparser.ast.expr.SingleMemberAnnotationExpr;

import java.util.Optional;

/**
 * 提取接口方法中文说明：@Operation(summary) &gt; @Operation(description) &gt; Javadoc 首段。
 */
public final class MethodDescriptionExtractor {
    private MethodDescriptionExtractor() {
    }

    public static String extract(MethodDeclaration method) {
        if (method == null) {
            return "";
        }
        for (AnnotationExpr annotation : method.getAnnotations()) {
            if (!"Operation".equals(annotation.getNameAsString())) {
                continue;
            }
            String summary = readAnnotationStringValue(annotation, "summary");
            if (!summary.isEmpty()) {
                return summary;
            }
            String description = readAnnotationStringValue(annotation, "description");
            if (!description.isEmpty()) {
                return description;
            }
        }
        return extractMethodJavadoc(method);
    }

    private static String extractMethodJavadoc(MethodDeclaration method) {
        Optional<JavadocComment> javadoc = method.getJavadocComment();
        if (javadoc.isEmpty()) {
            return "";
        }
        String text = javadoc.get().parse().getDescription().toText();
        return text == null ? "" : text.trim().replaceAll("\\s+", " ");
    }

    private static String readAnnotationStringValue(AnnotationExpr annotation, String attributeName) {
        if (annotation.isNormalAnnotationExpr()) {
            NormalAnnotationExpr normal = annotation.asNormalAnnotationExpr();
            for (var pair : normal.getPairs()) {
                if (pair.getNameAsString().equals(attributeName)) {
                    return literalString(pair.getValue());
                }
            }
            return "";
        }
        if (annotation.isSingleMemberAnnotationExpr()) {
            SingleMemberAnnotationExpr single = annotation.asSingleMemberAnnotationExpr();
            if ("value".equals(attributeName) || "description".equals(attributeName)
                    || "summary".equals(attributeName)) {
                return literalString(single.getMemberValue());
            }
        }
        return "";
    }

    private static String literalString(Expression expression) {
        if (expression.isStringLiteralExpr()) {
            return expression.asStringLiteralExpr().getValue().trim();
        }
        return "";
    }
}
