package hudson.plugins.git;

import com.cloudbees.plugins.credentials.*;
import com.cloudbees.plugins.credentials.common.StandardCredentials;
import com.cloudbees.plugins.credentials.domains.Domain;
import com.cloudbees.plugins.credentials.impl.UsernamePasswordCredentialsImpl;
import jenkins.model.Jenkins;
import jenkins.plugins.git.GitSampleRepoRule;
import org.jenkinsci.plugins.workflow.cps.CpsFlowDefinition;
import org.jenkinsci.plugins.workflow.job.WorkflowJob;
import org.jenkinsci.plugins.workflow.job.WorkflowRun;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.jvnet.hudson.test.Issue;
import org.jvnet.hudson.test.JenkinsRule;

import java.util.Collections;

import static org.hamcrest.Matchers.notNullValue;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertThat;

public class CredentialsUserRemoteConfigTest {

    @Rule
    public JenkinsRule r = new JenkinsRule();

    @Rule
    public GitSampleRepoRule sampleRepo = new GitSampleRepoRule();

    private CredentialsStore store = null;

    @Before
    public void enableSystemCredentialsProvider() {
        SystemCredentialsProvider.getInstance().setDomainCredentialsMap(
                Collections.singletonMap(Domain.global(), Collections.<Credentials>emptyList()));
        for (CredentialsStore s : CredentialsProvider.lookupStores(Jenkins.getInstance())) {
            if (s.getProvider() instanceof SystemCredentialsProvider.ProviderImpl) {
                store = s;
                break;
            }
        }
        assertThat("The system credentials provider is enabled", store, notNullValue());
    }

    @Issue("JENKINS-30515")
    @Test
    public void checkoutWithValidCredentials() throws Exception {
        sampleRepo.init();
        store.addCredentials(Domain.global(), createCredential(CredentialsScope.GLOBAL, "github"));
        store.save();

        WorkflowJob p = r.jenkins.createProject(WorkflowJob.class, "p");
        p.setDefinition(new CpsFlowDefinition(
                "node {\n"
                        + "  checkout(\n"
                        + "    [$class: 'GitSCM', \n"
                        + "      userRemoteConfigs: [[credentialsId: 'github', url: $/" + sampleRepo + "/$, branches: [[name: '*/master']], doGenerateSubmoduleConfigurations: false]]]\n"
                        + "  )"
                        + "}"));
        WorkflowRun b = r.assertBuildStatusSuccess(p.scheduleBuild2(0));
        r.assertLogContains("using credential github", b);
    }

    @Issue("JENKINS-30515")
    @Test
    public void checkoutWithDifferentCredentials() throws Exception {
        sampleRepo.init();
        store.addCredentials(Domain.global(), createCredential(CredentialsScope.GLOBAL, "other"));
        store.save();

        WorkflowJob p = r.jenkins.createProject(WorkflowJob.class, "p");
        p.setDefinition(new CpsFlowDefinition(
                "node {\n"
                        + "  checkout(\n"
                        + "    [$class: 'GitSCM', \n"
                        + "      userRemoteConfigs: [[credentialsId: 'github', url: $/" + sampleRepo + "/$, branches: [[name: '*/master']], doGenerateSubmoduleConfigurations: false]]]\n"
                        + "  )"
                        + "}"));
        WorkflowRun b = r.assertBuildStatusSuccess(p.scheduleBuild2(0));
        System.out.println(JenkinsRule.getLog(b));
        r.assertLogContains("Warning: CredentialId \"github\" could not be found", b);
    }

    @Issue("JENKINS-30515")
    @Test
    public void checkoutWithInvalidCredentials() throws Exception {
        sampleRepo.init();
        store.addCredentials(Domain.global(), createCredential(CredentialsScope.SYSTEM, "github"));
        store.save();

        WorkflowJob p = r.jenkins.createProject(WorkflowJob.class, "p");
        p.setDefinition(new CpsFlowDefinition(
                "node {\n"
                        + "  checkout(\n"
                        + "    [$class: 'GitSCM', \n"
                        + "      userRemoteConfigs: [[credentialsId: 'github', url: $/" + sampleRepo + "/$, branches: [[name: '*/master']], doGenerateSubmoduleConfigurations: false]]]\n"
                        + "  )"
                        + "}"));
        WorkflowRun b = r.assertBuildStatusSuccess(p.scheduleBuild2(0));
        r.assertLogContains("Warning: CredentialId \"github\" could not be found", b);
    }

    @Issue("JENKINS-30515")
    @Test
    public void checkoutWithNoCredentialsStoredButUsed() throws Exception {
        sampleRepo.init();

        WorkflowJob p = r.jenkins.createProject(WorkflowJob.class, "p");
        p.setDefinition(new CpsFlowDefinition(
                "node {\n"
                        + "  checkout(\n"
                        + "    [$class: 'GitSCM', \n"
                        + "      userRemoteConfigs: [[credentialsId: 'github', url: $/" + sampleRepo + "/$, branches: [[name: '*/master']], doGenerateSubmoduleConfigurations: false]]]\n"
                        + "  )"
                        + "}"));
        WorkflowRun b = r.assertBuildStatusSuccess(p.scheduleBuild2(0));
        System.out.println(JenkinsRule.getLog(b));
        r.assertLogContains("Warning: CredentialId \"github\" could not be found", b);
    }

    @Issue("JENKINS-30515")
    @Test
    public void checkoutWithNoCredentialsSpecified() throws Exception {
        sampleRepo.init();

        WorkflowJob p = r.jenkins.createProject(WorkflowJob.class, "p");
        p.setDefinition(new CpsFlowDefinition(
                "node {\n"
                        + "  checkout(\n"
                        + "    [$class: 'GitSCM', \n"
                        + "      userRemoteConfigs: [[url: $/" + sampleRepo + "/$, branches: [[name: '*/master']], doGenerateSubmoduleConfigurations: false]]]\n"
                        + "  )"
                        + "}"));
        WorkflowRun b = r.assertBuildStatusSuccess(p.scheduleBuild2(0));
        System.out.println(JenkinsRule.getLog(b));
        r.assertLogContains("No credentials specified", b);
    }


    private StandardCredentials createCredential(CredentialsScope scope, String id) {
        return new UsernamePasswordCredentialsImpl(scope, id, "desc: " + id, "username", "password");
    }
}

@@ -2255,89 +2255,15 @@
  %22/$
-, branches: %5B%5Bname: '*/master'%5D%5D, doGenerateSubmoduleConfigurations: false
 %5D%5D%5D%5Cn%22%0A
+
     
@@ -3072,82 +3072,8 @@
  %22/$
-, branches: %5B%5Bname: '*/master'%5D%5D, doGenerateSubmoduleConfigurations: false
 %5D%5D%5D%5C
@@ -3967,82 +3967,8 @@
  %22/$
-, branches: %5B%5Bname: '*/master'%5D%5D, doGenerateSubmoduleConfigurations: false
 %5D%5D%5D%5C
@@ -4697,82 +4697,8 @@
  %22/$
-, branches: %5B%5Bname: '*/master'%5D%5D, doGenerateSubmoduleConfigurations: false
 %5D%5D%5D%5C
@@ -5356,32 +5356,32 @@
 : 'GitSCM', %5Cn%22%0A
+
                 
@@ -5449,82 +5449,8 @@
  %22/$
-, branches: %5B%5Bname: '*/master'%5D%5D, doGenerateSubmoduleConfigurations: false
 %5D%5D%5D%5C

Fix structs 1.20 CredentialsUserRemoteConfigTest