/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to you under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.apache.calcite.avatica;

import org.apache.calcite.avatica.jdbc.JdbcMeta;
import org.apache.calcite.avatica.remote.Driver;
import org.apache.calcite.avatica.remote.LocalService;
import org.apache.calcite.avatica.server.HttpServer;
import org.apache.calcite.avatica.util.DateTimeUtils;

import org.bouncycastle.asn1.x500.X500Name;
import org.bouncycastle.asn1.x500.style.IETFUtils;
import org.bouncycastle.asn1.x500.style.RFC4519Style;
import org.bouncycastle.asn1.x509.BasicConstraints;
import org.bouncycastle.asn1.x509.Extension;
import org.bouncycastle.asn1.x509.KeyUsage;
import org.bouncycastle.cert.X509CertificateHolder;
import org.bouncycastle.cert.jcajce.JcaX509CertificateConverter;
import org.bouncycastle.cert.jcajce.JcaX509ExtensionUtils;
import org.bouncycastle.cert.jcajce.JcaX509v3CertificateBuilder;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import org.bouncycastle.operator.OperatorCreationException;
import org.bouncycastle.operator.jcajce.JcaContentSignerBuilder;
import org.junit.AfterClass;
import org.junit.BeforeClass;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
import org.junit.runners.Parameterized.Parameters;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.math.BigInteger;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.KeyStore;
import java.security.NoSuchAlgorithmException;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.Security;
import java.security.cert.Certificate;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.List;
import java.util.Objects;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import static org.junit.Assume.assumeFalse;

/**
 * Test case for Avatica with TLS connectors.
 */
@RunWith(Parameterized.class)
public class SslDriverTest {
  private static final Logger LOG = LoggerFactory.getLogger(SslDriverTest.class);

  private static final String KEYSTORE_PASSWORD = "avaticasecret";
  private static final ConnectionSpec CONNECTION_SPEC = ConnectionSpec.HSQLDB;
  private static final List<HttpServer> SERVERS_TO_STOP = new ArrayList<>();

  @Parameters public static List<Object[]> parameters() throws Exception {
    final ArrayList<Object[]> parameters = new ArrayList<>();

    // Create a self-signed cert
    File target = new File(System.getProperty("user.dir"), "target");
    File keystore = new File(target, "avatica-test.jks");
    if (keystore.isFile()) {
      assertTrue("Failed to delete keystore: " + keystore, keystore.delete());
    }
    new CertTool().createSelfSignedCert(keystore, "avatica", KEYSTORE_PASSWORD);

    // Create a LocalService around HSQLDB
    final JdbcMeta jdbcMeta = new JdbcMeta(CONNECTION_SPEC.url,
        CONNECTION_SPEC.username, CONNECTION_SPEC.password);
    final LocalService localService = new LocalService(jdbcMeta);

    for (Driver.Serialization serialization : new Driver.Serialization[] {
        Driver.Serialization.JSON, Driver.Serialization.PROTOBUF}) {
      // Build and start the server, using TLS
      HttpServer httpServer = new HttpServer.Builder()
          .withPort(0)
          .withTLS(keystore, KEYSTORE_PASSWORD, keystore, KEYSTORE_PASSWORD)
          .withHandler(localService, serialization)
          .build();
      httpServer.start();
      SERVERS_TO_STOP.add(httpServer);

      final String url = "jdbc:avatica:remote:url=https://localhost:" + httpServer.getPort()
          + ";serialization=" + serialization + ";truststore=" + keystore.getAbsolutePath()
          + ";truststore_password=" + KEYSTORE_PASSWORD;
      LOG.info("JDBC URL {}", url);

      parameters.add(new Object[] {url});
    }

    return parameters;
  }

  @BeforeClass public static void setupClass() {
    // Skip TLS testing on IBM Java due the combination of:
    // - Jetty 9.4.12+ ignores SSL_* ciphers due to security - eclipse/jetty.project#2807
    // - IBM uses SSL_* cipher names for ALL ciphers not following RFC cipher names
    //   See eclipse/jetty.project#2807 for details
    assumeFalse(System.getProperty("java.vendor").contains("IBM"));
  }

  @AfterClass public static void stopKdc() {
    for (HttpServer server : SERVERS_TO_STOP) {
      server.stop();
    }
  }

  private final String jdbcUrl;

  public SslDriverTest(String jdbcUrl) {
    this.jdbcUrl = Objects.requireNonNull(jdbcUrl);
  }

  @Test
  public void testReadWrite() throws Exception {
    final String tableName = "testReadWrite";
    try (Connection conn = DriverManager.getConnection(jdbcUrl);
        Statement stmt = conn.createStatement()) {
      assertFalse(stmt.execute("DROP TABLE IF EXISTS " + tableName));
      assertFalse(stmt.execute("CREATE TABLE " + tableName + "(pk integer)"));
      assertEquals(1, stmt.executeUpdate("INSERT INTO " + tableName + " VALUES(1)"));
      assertEquals(1, stmt.executeUpdate("INSERT INTO " + tableName + " VALUES(2)"));
      assertEquals(1, stmt.executeUpdate("INSERT INTO " + tableName + " VALUES(3)"));

      ResultSet results = stmt.executeQuery("SELECT count(1) FROM " + tableName);
      assertTrue(results.next());
      assertEquals(3, results.getInt(1));
    }
  }

  /**
   * Utility class for creating certificates for testing.
   */
  private static class CertTool {
    private static final String SIGNING_ALGORITHM = "SHA256WITHRSA";
    private static final String ENC_ALGORITHM = "RSA";

    static {
      Security.addProvider(new BouncyCastleProvider());
    }

    private void createSelfSignedCert(File targetKeystore, String keyName,
        String keystorePassword) {
      if (targetKeystore.exists()) {
        throw new RuntimeException("Keystore already exists: " + targetKeystore);
      }

      try {
        KeyPair kp = generateKeyPair();

        X509Certificate cert = generateCert(keyName, kp, true, kp.getPublic(),
            kp.getPrivate());

        char[] password = keystorePassword.toCharArray();
        KeyStore keystore = KeyStore.getInstance("JKS");
        keystore.load(null, null);
        keystore.setCertificateEntry(keyName + "Cert", cert);
        keystore.setKeyEntry(keyName + "Key", kp.getPrivate(), password, new Certificate[] {cert});
        try (FileOutputStream fos = new FileOutputStream(targetKeystore)) {
          keystore.store(fos, password);
        }
      } catch (Exception e) {
        throw new RuntimeException(e);
      }
    }

    private KeyPair generateKeyPair() throws NoSuchAlgorithmException {
      KeyPairGenerator gen = KeyPairGenerator.getInstance(ENC_ALGORITHM);
      gen.initialize(2048);
      return gen.generateKeyPair();
    }

    private X509Certificate generateCert(String keyName, KeyPair kp, boolean isCertAuthority,
                                         PublicKey signerPublicKey, PrivateKey signerPrivateKey)
        throws IOException, OperatorCreationException, CertificateException,
        NoSuchAlgorithmException {
      Calendar startDate = DateTimeUtils.calendar();
      Calendar endDate = DateTimeUtils.calendar();
      endDate.add(Calendar.YEAR, 100);

      BigInteger serialNumber = BigInteger.valueOf(startDate.getTimeInMillis());
      X500Name issuer = new X500Name(
          IETFUtils.rDNsFromString("cn=localhost", RFC4519Style.INSTANCE));
      JcaX509v3CertificateBuilder certGen = new JcaX509v3CertificateBuilder(issuer,
          serialNumber, startDate.getTime(), endDate.getTime(), issuer, kp.getPublic());
      JcaX509ExtensionUtils extensionUtils = new JcaX509ExtensionUtils();
      certGen.addExtension(Extension.subjectKeyIdentifier, false,
          extensionUtils.createSubjectKeyIdentifier(kp.getPublic()));
      certGen.addExtension(Extension.basicConstraints, false,
          new BasicConstraints(isCertAuthority));
      certGen.addExtension(Extension.authorityKeyIdentifier, false,
          extensionUtils.createAuthorityKeyIdentifier(signerPublicKey));
      if (isCertAuthority) {
        certGen.addExtension(Extension.keyUsage, true, new KeyUsage(KeyUsage.keyCertSign));
      }
      X509CertificateHolder certificateHolder = certGen.build(
          new JcaContentSignerBuilder(SIGNING_ALGORITHM).build(signerPrivateKey));
      return new JcaX509CertificateConverter().getCertificate(certificateHolder);
    }
  }
}

// End SslDriverTest.java
