/*
 * 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.druid.utils;

import com.google.common.collect.ImmutableSet;
import org.apache.druid.java.util.common.IAE;
import org.junit.Assert;
import org.junit.Rule;
import org.junit.Test;
import org.junit.experimental.runners.Enclosed;
import org.junit.rules.ExpectedException;
import org.junit.runner.RunWith;
import org.mockito.MockedStatic;
import org.mockito.Mockito;

import java.util.Set;

@RunWith(Enclosed.class)
public class ConnectionUriUtilsTest
{
  public static class ThrowIfURLHasNotAllowedPropertiesTest
  {
    private static final String MYSQL_URI = "jdbc:mysql://localhost:3306/test?user=druid&password=diurd&keyonly&otherOptions=wat";
    private static final String MARIA_URI = "jdbc:mariadb://localhost:3306/test?user=druid&password=diurd&keyonly&otherOptions=wat";
    private static final String POSTGRES_URI = "jdbc:postgresql://localhost:3306/test?user=druid&password=diurd&keyonly&otherOptions=wat";
    private static final String UNKNOWN_URI = "jdbc:druid://localhost:8888/query/v2/sql/avatica?user=druid&password=diurd&keyonly&otherOptions=wat";

    @Rule
    public ExpectedException expectedException = ExpectedException.none();

    @Test
    public void testEmptyActualProperties()
    {
      ConnectionUriUtils.throwIfPropertiesAreNotAllowed(
          ImmutableSet.of(),
          ImmutableSet.of("valid_key1", "valid_key2"),
          ImmutableSet.of("system_key1", "system_key2")
      );
    }

    @Test
    public void testThrowForNonAllowedProperties()
    {
      expectedException.expect(IllegalArgumentException.class);
      expectedException.expectMessage("The property [invalid_key] is not in the allowed list [valid_key1, valid_key2]");

      ConnectionUriUtils.throwIfPropertiesAreNotAllowed(
          ImmutableSet.of("valid_key1", "invalid_key"),
          ImmutableSet.of("system_key1", "system_key2"),
          ImmutableSet.of("valid_key1", "valid_key2")
      );
    }

    @Test
    public void testAllowedProperties()
    {
      ConnectionUriUtils.throwIfPropertiesAreNotAllowed(
          ImmutableSet.of("valid_key2"),
          ImmutableSet.of("system_key1", "system_key2"),
          ImmutableSet.of("valid_key1", "valid_key2")
      );
    }

    @Test
    public void testAllowSystemProperties()
    {
      ConnectionUriUtils.throwIfPropertiesAreNotAllowed(
          ImmutableSet.of("system_key1", "valid_key2"),
          ImmutableSet.of("system_key1", "system_key2"),
          ImmutableSet.of("valid_key1", "valid_key2")
      );
    }

    @Test
    public void testMatchSystemProperties()
    {
      ConnectionUriUtils.throwIfPropertiesAreNotAllowed(
          ImmutableSet.of("system_key1.1", "system_key1.5", "system_key11.11", "valid_key2"),
          ImmutableSet.of("system_key1", "system_key2"),
          ImmutableSet.of("valid_key1", "valid_key2")
      );
    }

    @Test
    public void testTryParses()
    {
      Set<String> props = ConnectionUriUtils.tryParseJdbcUriParameters(POSTGRES_URI, false);
      Assert.assertEquals(7, props.size());

      props = ConnectionUriUtils.tryParseJdbcUriParameters(MYSQL_URI, false);
      // though this would be 4 if mysql wasn't loaded in classpath because it would fall back to mariadb
      Assert.assertEquals(9, props.size());

      props = ConnectionUriUtils.tryParseJdbcUriParameters(MARIA_URI, false);
      Assert.assertEquals(4, props.size());
    }

    @Test
    public void testTryParseUnknown()
    {
      Set<String> props = ConnectionUriUtils.tryParseJdbcUriParameters(UNKNOWN_URI, true);
      Assert.assertEquals(0, props.size());

      expectedException.expect(IAE.class);
      ConnectionUriUtils.tryParseJdbcUriParameters(UNKNOWN_URI, false);
    }

    @Test
    public void tryParseInvalidPostgres()
    {
      expectedException.expect(IAE.class);
      ConnectionUriUtils.tryParseJdbcUriParameters("jdbc:postgresql://bad:1234&param", true);
    }

    @Test
    public void tryParseInvalidMySql()
    {
      expectedException.expect(IAE.class);
      ConnectionUriUtils.tryParseJdbcUriParameters("jdbc:mysql:/bad", true);
    }

    @Test
    public void testMySqlFallbackMySqlMaria2x()
    {
      MockedStatic<ConnectionUriUtils> utils = Mockito.mockStatic(ConnectionUriUtils.class);
      utils.when(() -> ConnectionUriUtils.tryParseJdbcUriParameters(MYSQL_URI, false)).thenCallRealMethod();
      utils.when(() -> ConnectionUriUtils.tryParseMySqlConnectionUri(MYSQL_URI)).thenThrow(ClassNotFoundException.class);
      utils.when(() -> ConnectionUriUtils.tryParseMariaDb2xConnectionUri(MYSQL_URI)).thenCallRealMethod();

      Set<String> props = ConnectionUriUtils.tryParseJdbcUriParameters(MYSQL_URI, false);
      // this would be 9 if didn't fall back to mariadb
      Assert.assertEquals(4, props.size());
      utils.close();
    }

    @Test
    public void testMariaFallbackMaria3x()
    {
      MockedStatic<ConnectionUriUtils> utils = Mockito.mockStatic(ConnectionUriUtils.class);
      utils.when(() -> ConnectionUriUtils.tryParseJdbcUriParameters(MARIA_URI, false)).thenCallRealMethod();
      utils.when(() -> ConnectionUriUtils.tryParseMariaDb2xConnectionUri(MARIA_URI)).thenThrow(ClassNotFoundException.class);
      utils.when(() -> ConnectionUriUtils.tryParseMariaDb3xConnectionUri(MARIA_URI)).thenCallRealMethod();

      try {
        Set<String> props = ConnectionUriUtils.tryParseJdbcUriParameters(MARIA_URI, false);
        // this would be 4 if didn't fall back to mariadb 3x
        Assert.assertEquals(8, props.size());
      }
      catch (RuntimeException e) {

        Assert.assertTrue(e.getMessage().contains("Failed to find MariaDB driver class"));
      }
      utils.close();
    }

    @Test
    public void testMySqlFallbackMySqlNoDrivers()
    {
      MockedStatic<ConnectionUriUtils> utils = Mockito.mockStatic(ConnectionUriUtils.class);
      utils.when(() -> ConnectionUriUtils.tryParseJdbcUriParameters(MYSQL_URI, false)).thenCallRealMethod();
      utils.when(() -> ConnectionUriUtils.tryParseMySqlConnectionUri(MYSQL_URI)).thenThrow(ClassNotFoundException.class);
      utils.when(() -> ConnectionUriUtils.tryParseMariaDb2xConnectionUri(MYSQL_URI)).thenThrow(ClassNotFoundException.class);

      try {
        ConnectionUriUtils.tryParseJdbcUriParameters(MYSQL_URI, false);
      }
      catch (RuntimeException e) {
        Assert.assertTrue(e.getMessage().contains("Failed to find MySQL driver class"));
      }
      utils.close();
    }

    @Test
    public void testPosgresDriver() throws Exception
    {
      Set<String> props = ConnectionUriUtils.tryParsePostgresConnectionUri(POSTGRES_URI);
      Assert.assertEquals(7, props.size());
      // postgres adds a few extra system properties, PGDBNAME, PGHOST, PGPORT
      Assert.assertTrue(props.contains("user"));
      Assert.assertTrue(props.contains("password"));
      Assert.assertTrue(props.contains("otherOptions"));
      Assert.assertTrue(props.contains("keyonly"));
    }

    @Test
    public void testMySQLDriver() throws Exception
    {
      Set<String> props = ConnectionUriUtils.tryParseMySqlConnectionUri(MYSQL_URI);
      // mysql actually misses 'keyonly', but spits out several keys that are not actually uri parameters
      // DBNAME, HOST, PORT, HOST.1, PORT.1, NUM_HOSTS
      Assert.assertEquals(9, props.size());
      Assert.assertTrue(props.contains("user"));
      Assert.assertTrue(props.contains("password"));
      Assert.assertTrue(props.contains("otherOptions"));
      Assert.assertFalse(props.contains("keyonly"));
    }

    @Test
    public void testMariaDb2xDriver() throws Throwable
    {
      Set<String> props = ConnectionUriUtils.tryParseMariaDb2xConnectionUri(MYSQL_URI);
      // mariadb doesn't spit out any extras other than what the user specified
      Assert.assertEquals(4, props.size());
      Assert.assertTrue(props.contains("user"));
      Assert.assertTrue(props.contains("password"));
      Assert.assertTrue(props.contains("otherOptions"));
      Assert.assertTrue(props.contains("keyonly"));
      props = ConnectionUriUtils.tryParseMariaDb2xConnectionUri(MARIA_URI);
      Assert.assertEquals(4, props.size());
      Assert.assertTrue(props.contains("user"));
      Assert.assertTrue(props.contains("password"));
      Assert.assertTrue(props.contains("otherOptions"));
      Assert.assertTrue(props.contains("keyonly"));
    }

    @Test(expected = ClassNotFoundException.class)
    public void testMariaDb3xDriver() throws Exception
    {
      // at the time of adding this test, mariadb connector/j 3.x does not actually parse jdbc:mysql uris
      // so this would throw an IAE.class instead of ClassNotFoundException.class if the connector is swapped out
      // in maven dependencies
      ConnectionUriUtils.tryParseMariaDb3xConnectionUri(MYSQL_URI);
    }

    @Test(expected = ClassNotFoundException.class)
    public void testMariaDb3xDriverMariaUri() throws Exception
    {
      // mariadb 3.x driver cannot be loaded alongside 2.x, so this will fail with class not found
      // however, if we swap out version in pom then we end up with 8 keys where
      // "database", "addresses", "codecs", and "initialUrl" are added as extras
      // we should perhaps consider adding them to built-in allowed lists in the future when this driver is no longer
      // an alpha release
      Set<String> props = ConnectionUriUtils.tryParseMariaDb3xConnectionUri(MARIA_URI);
      Assert.assertEquals(8, props.size());
      Assert.assertTrue(props.contains("user"));
      Assert.assertTrue(props.contains("password"));
      Assert.assertTrue(props.contains("otherOptions"));
      Assert.assertTrue(props.contains("keyonly"));
    }

    @Test(expected = IAE.class)
    public void testPostgresInvalidArgs() throws Exception
    {
      ConnectionUriUtils.tryParsePostgresConnectionUri(MYSQL_URI);
    }

    @Test(expected = IAE.class)
    public void testMySqlInvalidArgs() throws Exception
    {
      ConnectionUriUtils.tryParseMySqlConnectionUri(POSTGRES_URI);
    }

    @Test(expected = IAE.class)
    public void testMariaDbInvalidArgs() throws Exception
    {
      ConnectionUriUtils.tryParseMariaDb2xConnectionUri(POSTGRES_URI);
    }
  }
}
