package com.aicheck.parser;

import com.github.javaparser.StaticJavaParser;
import com.github.javaparser.ast.CompilationUnit;
import com.github.javaparser.ast.body.ClassOrInterfaceDeclaration;
import com.github.javaparser.ast.body.MethodDeclaration;
import com.github.javaparser.ast.body.TypeDeclaration;
import com.github.javaparser.ast.expr.MethodCallExpr;
import com.github.javaparser.ast.visitor.VoidVisitorAdapter;

import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.LinkedHashSet;
import java.util.Set;
import java.util.stream.Stream;

/**
 * 扫描 Dto→Entity 转换关系：convert 方法返回值、BeanUtils.copyProperties 调用。
 */
public class ConversionParser {

    /** 在类内查找 convert 方法，收集返回 Entity 的类型名 */
    public Set<String> findConvertTargetsInClass(String source, String className) {
        Set<String> entities = new LinkedHashSet<>();
        if (source == null || source.isBlank()) {
            return entities;
        }
        CompilationUnit cu = StaticJavaParser.parse(source);
        for (TypeDeclaration<?> type : cu.getTypes()) {
            if (type instanceof ClassOrInterfaceDeclaration) {
                ClassOrInterfaceDeclaration classDecl = (ClassOrInterfaceDeclaration) type;
                if (!classDecl.getNameAsString().equals(className)) {
                    continue;
                }
                for (MethodDeclaration method : classDecl.getMethods()) {
                    if (!"convert".equals(method.getNameAsString())) {
                        continue;
                    }
                    String returnType = TypeNameUtils.simpleName(TypeNameUtils.typeToString(method.getType()));
                    if (returnType.endsWith("Entity")) {
                        entities.add(returnType);
                    }
                }
            }
        }
        return entities;
    }

    /** 递归扫描目录，查找 BeanUtils.copyProperties(sourceClass, *Entity) */
    public Set<String> findBeanUtilsTargets(Path rootDir, String sourceClassName) throws IOException {
        Set<String> entities = new LinkedHashSet<>();
        if (!Files.exists(rootDir)) {
            return entities;
        }
        try (Stream<Path> paths = Files.walk(rootDir)) {
            paths.filter(path -> path.toString().endsWith(".java")).forEach(path -> {
                try {
                    String source = Files.readString(path, StandardCharsets.UTF_8);
                    entities.addAll(scanBeanUtilsInSource(source, sourceClassName));
                } catch (IOException ignored) {
                    // 跳过
                }
            });
        }
        return entities;
    }

    /** 在单文件源码中扫描 BeanUtils.copyProperties 调用 */
    private Set<String> scanBeanUtilsInSource(String source, String sourceClassName) {
        Set<String> entities = new LinkedHashSet<>();
        CompilationUnit cu = StaticJavaParser.parse(source);
        cu.accept(new VoidVisitorAdapter<Void>() {
            @Override
            public void visit(MethodCallExpr call, Void arg) {
                super.visit(call, arg);
                if (!call.getNameAsString().equals("copyProperties")) {
                    return;
                }
                if (call.getScope().isEmpty()) {
                    return;
                }
                String scope = call.getScope().get().toString();
                if (!scope.endsWith("BeanUtils")) {
                    return;
                }
                if (call.getArguments().size() < 2) {
                    return;
                }
                String firstArg = TypeNameUtils.simpleName(call.getArguments().get(0).toString());
                String secondArg = TypeNameUtils.simpleName(call.getArguments().get(1).toString());
                if (sourceClassName.equals(firstArg) && secondArg.endsWith("Entity")) {
                    entities.add(secondArg);
                }
            }
        }, null);
        return entities;
    }
}
