package dp.kotul.bamboospecsapplication.creator;

import com.atlassian.bamboo.specs.api.builders.task.Task;
import com.atlassian.bamboo.specs.builders.task.DockerBuildImageTask;
import com.atlassian.bamboo.specs.builders.task.DockerPushImageTask;
import com.atlassian.bamboo.specs.builders.task.InjectVariablesTask;
import com.atlassian.bamboo.specs.builders.task.MavenTask;
import com.atlassian.bamboo.specs.builders.task.NpmTask;
import com.atlassian.bamboo.specs.builders.task.ScriptTask;
import com.atlassian.bamboo.specs.builders.task.VcsCheckoutTask;
import dp.kotul.bamboospecsapplication.configuration.BuildTaskConfiguration;
import java.security.InvalidParameterException;
import java.util.ArrayList;
import java.util.List;

public class BuildTaskCreator {
    private BuildTaskCreator(){}

    public static Task[] createBuildTasks(List<BuildTaskConfiguration> tasksFromConfig) {
        List<Task> tasks = new ArrayList<>();
        tasks.add(createCheckoutTask());
        for (BuildTaskConfiguration task : tasksFromConfig) {
            tasks.add(createTask(task));
        }
        return tasks.stream().toArray(Task[]::new);
    }

    private static VcsCheckoutTask createCheckoutTask() {
        return new VcsCheckoutTask()
                .description("Checkout Default Repository")
                .addCheckoutOfDefaultRepository()
                .cleanCheckout(true);
    }

    private static Task createTask(BuildTaskConfiguration taskConfig) {
        switch (taskConfig.getType()) {
            case MAVEN: return createMavenTask(taskConfig);
            case SCRIPT: return createScriptTask(taskConfig);
            case NPM: return createNpmTask(taskConfig);
            case INJECT_VARIABLE: return createInjectVariableTaks(taskConfig);
            case DOCKER_BUILD: return createDockerImageBuildTask(taskConfig);
            case DOCKER_PUSH: return createDockerImagePushTask(taskConfig);
            default: throw new InvalidParameterException(taskConfig.getType() + " task is not supported");
        }
    }

    private static Task createInjectVariableTaks(BuildTaskConfiguration taskConfig) {
        return new InjectVariablesTask()
                .description(taskConfig.getDescription())
                .path(taskConfig.getPath())
                .namespace(taskConfig.getNamespace())
                .scopeResult();
    }

    private static Task createScriptTask(BuildTaskConfiguration taskConfig) {
        return new ScriptTask()
                .description(taskConfig.getDescription())
                .interpreterBinSh()
                .inlineBody(String.join("\n", taskConfig.getContent()));
    }

    private static Task createMavenTask(BuildTaskConfiguration taskConfig) {
        return new MavenTask()
                .description(taskConfig.getDescription())
                .executableLabel("Maven 3")
                .goal(String.join("\n", taskConfig.getContent()))
                .jdk("Java 12")
                .hasTests(taskConfig.getHasTests())
                .environmentVariables(taskConfig.getEnvironmentVariables());
    }

    private static Task createNpmTask(BuildTaskConfiguration taskConfig) {
        return new NpmTask()
                .description(taskConfig.getDescription())
                .nodeExecutable("Node.js")
                .command(String.join("\n", taskConfig.getContent()));
    }

    private static Task createDockerImageBuildTask(BuildTaskConfiguration taskConfig) {
        return new DockerBuildImageTask()
                .description(taskConfig.getDescription())
                .dockerfileInWorkingDir()
                .useCache(true)
                .imageName(taskConfig.getImageName())
                .workingSubdirectory(taskConfig.getWorkingDirectory());
    }

    private static Task createDockerImagePushTask(BuildTaskConfiguration taskConfig) {
        return new DockerPushImageTask()
                .description(taskConfig.getDescription())
                .customRegistryImage(taskConfig.getImageName())
                .defaultAuthentication();
    }
}
