package jetbrains.buildServer.deployer.agent.cargo;

import com.intellij.openapi.util.io.StreamUtil;
import jetbrains.buildServer.NetworkUtil;
import jetbrains.buildServer.RunBuildException;
import jetbrains.buildServer.agent.*;
import jetbrains.buildServer.deployer.agent.BaseDeployerTest;
import jetbrains.buildServer.deployer.agent.util.DeployTestUtils;
import jetbrains.buildServer.deployer.common.CargoRunnerConstants;
import jetbrains.buildServer.deployer.common.DeployerRunnerConstants;
import jetbrains.buildServer.util.FileUtil;
import org.codehaus.cargo.container.ContainerType;
import org.codehaus.cargo.container.InstalledLocalContainer;
import org.codehaus.cargo.container.configuration.LocalConfiguration;
import org.codehaus.cargo.container.installer.ZipURLInstaller;
import org.codehaus.cargo.container.property.GeneralPropertySet;
import org.codehaus.cargo.container.property.ServletPropertySet;
import org.codehaus.cargo.container.tomcat.Tomcat7xStandaloneLocalConfiguration;
import org.codehaus.cargo.container.tomcat.TomcatPropertySet;
import org.codehaus.cargo.generic.DefaultContainerFactory;
import org.jmock.Expectations;
import org.jmock.Mockery;
import org.testng.annotations.AfterMethod;
import org.testng.annotations.BeforeMethod;
import org.testng.annotations.Test;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.util.HashMap;
import java.util.Map;

import static org.assertj.core.api.Assertions.assertThat;

/**
 * Created by Nikita.Skvortsov
 * Date: 10/3/12, 4:22 PM
 */
public class CargoBuildProcessAdapterHttpsTest extends BaseDeployerTest {

  private int testPort;
  private BuildRunnerContext myContext;
  private final Map<String, String> myRunnerParameters = new HashMap<String, String>();
  private InstalledLocalContainer myTomcat;
  private File workingDir;

  @BeforeMethod
  @Override
  public void setUp() throws Exception {

    final File extractDir = createTempDir();
    final File cfgDir = createTempDir();

    final String fileName = "apache-tomcat-7.0.54.zip";
    final File zipDistribution = getTestResource(fileName);
    final ZipURLInstaller installer = new ZipURLInstaller(zipDistribution.toURI().toURL());

    installer.setExtractDir(extractDir.getAbsolutePath());
    installer.install();

    LocalConfiguration configuration = new Tomcat7xStandaloneLocalConfiguration(cfgDir.getAbsolutePath());
    testPort = NetworkUtil.getFreePort(DEPLOYER_DEFAULT_PORT);
    configuration.setProperty(ServletPropertySet.PORT, String.valueOf(testPort));
    configuration.setProperty(ServletPropertySet.USERS, "tomcat:tomcat:manager-script");

    configuration.setProperty(TomcatPropertySet.AJP_PORT, String.valueOf(NetworkUtil.getFreePort(8009)));
    configuration.setProperty(TomcatPropertySet.CONNECTOR_KEY_STORE_FILE, getTestResource("ftpserver.jks").getAbsolutePath());
    configuration.setProperty(TomcatPropertySet.CONNECTOR_KEY_STORE_PASSWORD, "password");
    configuration.setProperty(TomcatPropertySet.CONNECTOR_KEY_ALIAS, "localhost");
    configuration.setProperty(TomcatPropertySet.HTTP_SECURE, "true");
    configuration.setProperty(GeneralPropertySet.PROTOCOL, "https");

    myTomcat = (InstalledLocalContainer) new DefaultContainerFactory().createContainer(
        "tomcat7x", ContainerType.INSTALLED, configuration);

    myTomcat.setHome(installer.getHome());

    myTomcat.start();

    Mockery mockeryCtx = new Mockery();
    myContext = mockeryCtx.mock(BuildRunnerContext.class);
    final AgentRunningBuild build = mockeryCtx.mock(AgentRunningBuild.class);
    final BuildProgressLogger logger = new NullBuildProgressLogger();
    workingDir = createTempDir();

    mockeryCtx.checking(new Expectations() {{
      allowing(myContext).getWorkingDirectory();
      will(returnValue(workingDir));
      allowing(myContext).getBuild();
      will(returnValue(build));
      allowing(myContext).getRunnerParameters();
      will(returnValue(myRunnerParameters));
      allowing(build).getBuildLogger();
      will(returnValue(logger));
    }});

    myRunnerParameters.put(DeployerRunnerConstants.PARAM_CONTAINER_TYPE, "tomcat7x");
    myRunnerParameters.put(CargoRunnerConstants.USE_HTTPS, "true");
  }

  @AfterMethod
  @Override
  public void tearDown() throws Exception {
    myTomcat.stop();
    super.tearDown();
  }

  @Test
  public void testSimpleDeploy() throws Exception {
    enableDebug();
    deployTestResourceAsArtifact("simple.war", "simple.war");
    assertUrlReturns(new URL("https://localhost:" + testPort + "/simple"), "Hello!  The time is now");
  }

  private void assertUrlReturns(URL url, String expected2) throws IOException {
    final InputStream stream2 = url.openStream();
    final String text2 = StreamUtil.readText(stream2);
    assertTrue(text2.contains(expected2));
  }


  private void deployTestResourceAsArtifact(String testResourceName, String artifactName) throws IOException, RunBuildException {
    FileUtil.copy(getTestResource(testResourceName), new File(workingDir, artifactName));
    final BuildProcess process = getProcess("localhost:" + testPort, artifactName);
    DeployTestUtils.runProcess(process, 5000);
  }

  private BuildProcess getProcess(String target, String sourcePath) {
    String username = "tomcat";
    String password = "tomcat";
    return new CargoBuildProcessAdapter(target, username, password, myContext, sourcePath);
  }
}

@@ -1289,16 +1289,129 @@
 .Test;%0A%0A
+import javax.net.ssl.HostnameVerifier;%0Aimport javax.net.ssl.HttpsURLConnection;%0Aimport javax.net.ssl.SSLSession;%0A
 import j
@@ -1423,16 +1423,16 @@
 o.File;%0A
-
 import j
@@ -1479,16 +1479,45 @@
 Stream;%0A
+import java.net.InetAddress;%0A
 import j
@@ -1999,16 +1999,70 @@
 kingDir;
+%0A  private HostnameVerifier myDefaultHostnameVerifier;
 %0A%0A  @Bef
@@ -3391,24 +3391,398 @@
  %22https%22);%0A%0A
+    myDefaultHostnameVerifier = HttpsURLConnection.getDefaultHostnameVerifier();%0A%0A    HttpsURLConnection.setDefaultHostnameVerifier(new HostnameVerifier() %7B%0A      @Override%0A      public boolean verify(String s, SSLSession sslSession) %7B%0A        return true; // new versions of Java do not allow to connect to localhost by SSL, here we suppress this behavior%0A      %7D%0A    %7D);%0A%0A
     myTomcat
@@ -4894,24 +4894,102 @@
 cat.stop();%0A
+    HttpsURLConnection.setDefaultHostnameVerifier(myDefaultHostnameVerifier);%0A
     super.te
@@ -5702,24 +5702,129 @@
 factName));%0A
+    InetAddress addr = NetworkUtil.getSelfAddresses(null)%5B0%5D;%0A    String hostname = addr.getHostName();%0A%0A
     final Bu
@@ -5855,26 +5855,28 @@
 Process(
-%22localhost
+hostname + %22
 :%22 + tes

fix test on new JVM