package com.ruoyi.platform.utils;

import org.eclipse.jgit.api.*;
import org.eclipse.jgit.api.errors.GitAPIException;
import org.eclipse.jgit.lib.Repository;
import org.eclipse.jgit.storage.file.FileRepositoryBuilder;
import org.eclipse.jgit.transport.CredentialsProvider;
import org.eclipse.jgit.transport.UsernamePasswordCredentialsProvider;

import java.io.*;
import java.nio.file.*;

public class DVCUtils {

    private static void runCommand(String command, String workingDir) throws Exception {
        ProcessBuilder processBuilder = new ProcessBuilder(command.split(" "));
        processBuilder.directory(new File(workingDir));
        Process process = processBuilder.start();
        BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream()));
        String line;
        while ((line = reader.readLine()) != null) {
            System.out.println(line);
        }
        int exitCode = process.waitFor();
        if (exitCode != 0) {
            throw new Exception("Command failed with exit code " + exitCode);
        }
    }

    public static void moveFiles(String sourcePath, String targetPath) throws Exception {
        Path sourceDir = Paths.get(sourcePath);
        Path targetDir = Paths.get(targetPath).resolve(sourceDir.getFileName());

        if (!Files.exists(targetDir)) {
            Files.createDirectories(targetDir);
        }

        Files.move(sourceDir, targetDir, StandardCopyOption.REPLACE_EXISTING);
    }

    public static void gitClone(String localPath, String repoUrl, String branch, String username, String password) throws GitAPIException {
        CloneCommand cloneCommand = Git.cloneRepository()
                .setURI(repoUrl)
                .setBranch(branch)
                .setDirectory(new java.io.File(localPath))
                .setCredentialsProvider(new UsernamePasswordCredentialsProvider(username, password));

        cloneCommand.call();
    }

    public static void gitAdd(String localPath, String filePath) throws IOException, GitAPIException {
        FileRepositoryBuilder builder = new FileRepositoryBuilder();
        Repository repository = builder.setGitDir(new File(localPath, ".git"))
                .readEnvironment()
                .findGitDir()
                .build();

        try (Git git = new Git(repository)) {
            AddCommand addCommand = git.add();
            addCommand.addFilepattern(filePath).call();
        }
    }

    public static void gitCommit(String localPath, String commitMessage) throws IOException, GitAPIException {
        FileRepositoryBuilder builder = new FileRepositoryBuilder();
        Repository repository = builder.setGitDir(new File(localPath, ".git"))
                .readEnvironment()
                .findGitDir()
                .build();

        try (Git git = new Git(repository)) {
            // 添加所有文件
            AddCommand addCommand = git.add();
            addCommand.addFilepattern(".").call();

            // 提交更改
            CommitCommand commitCommand = git.commit();
            commitCommand.setMessage(commitMessage).call();
        }
    }

    public static void gitPush(String localPath, String username, String password) throws IOException, GitAPIException {
        FileRepositoryBuilder builder = new FileRepositoryBuilder();
        Repository repository = builder.setGitDir(new File(localPath, ".git"))
                .readEnvironment()
                .findGitDir()
                .build();

        try (Git git = new Git(repository)) {
            CredentialsProvider credentialsProvider = new UsernamePasswordCredentialsProvider(username, password);
            PushCommand pushCommand = git.push();
            pushCommand.setCredentialsProvider(credentialsProvider)
                    .setForce(true)
                    .call();
        }
    }

    public static void gitCheckoutBranch(String localPath, String branchName) throws IOException, GitAPIException {
        FileRepositoryBuilder builder = new FileRepositoryBuilder();
        Repository repository = builder.setGitDir(new File(localPath, ".git"))
                .readEnvironment()
                .findGitDir()
                .build();

        try (Git git = new Git(repository)) {
            CheckoutCommand checkoutCommand = git.checkout();
            checkoutCommand.setName(branchName).call();
        }
    }

    public static void gitPull(String localPath, String username, String password) throws IOException, GitAPIException {
        FileRepositoryBuilder builder = new FileRepositoryBuilder();
        Repository repository = builder.setGitDir(new File(localPath, ".git"))
                .readEnvironment()
                .findGitDir()
                .build();

        try (Git git = new Git(repository)) {
            CredentialsProvider credentialsProvider = new UsernamePasswordCredentialsProvider(username, password);
            PullCommand pullCommand = git.pull();
            pullCommand.setCredentialsProvider(credentialsProvider).call();
        }
    }

    public static void dvcInit(String localPath) throws Exception {
        String command = "dvc init";
        runCommand(command, localPath);
    }

    public static void dvcAdd(String localPath, String filePath) throws Exception {
        String command = "dvc add " + filePath;
        runCommand(command, localPath);
    }

    public static void dvcRemoteAdd(String localPath, String s3RemoteUrl) throws Exception {
        String command = "dvc remote add -d myremote s3://" + s3RemoteUrl;
        runCommand(command, localPath);
    }

    public static void dvcConfigS3Credentials(String localPath, String endpointurl) throws Exception {
        String command = "dvc remote modify myremote endpointurl " + endpointurl;
        runCommand(command, localPath);
    }

    public static void dvcConfigS3Credentials2(String localPath, String accessKeyId) throws Exception {
        String command = "dvc remote modify myremote access_key_id " + accessKeyId;
        runCommand(command, localPath);
    }

    public static void dvcConfigS3Credentials3(String localPath, String secretAccessKey) throws Exception {
        String command = "dvc remote modify myremote secret_access_key " + secretAccessKey;
        runCommand(command, localPath);
    }

    public static void dvcPush(String localPath) throws Exception {
        String command = "dvc push";
        runCommand(command, localPath);
    }

    // 更新的 dvcPull 方法
    public static void dvcPull(String localPath) throws Exception {
        String command = "dvc pull";
        runCommand(command, localPath);
    }
}
