// Copyright (C) 2023 The Android Open Source Project
//
// Licensed 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 com.googlesource.gerrit.plugins.spannerrefdb;

import static com.googlesource.gerrit.plugins.spannerrefdb.Configuration.DATABASE_KEY;
import static com.googlesource.gerrit.plugins.spannerrefdb.Configuration.INSTANCE_KEY;
import static com.googlesource.gerrit.plugins.spannerrefdb.Configuration.SECTION;
import static com.googlesource.gerrit.plugins.spannerrefdb.Configuration.SUBSECTION;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;

import com.google.cloud.NoCredentials;
import com.google.cloud.spanner.Database;
import com.google.cloud.spanner.DatabaseAdminClient;
import com.google.cloud.spanner.DatabaseClient;
import com.google.cloud.spanner.Instance;
import com.google.cloud.spanner.InstanceAdminClient;
import com.google.cloud.spanner.InstanceConfigId;
import com.google.cloud.spanner.InstanceId;
import com.google.cloud.spanner.InstanceInfo;
import com.google.cloud.spanner.Spanner;
import com.google.cloud.spanner.SpannerOptions;
import com.google.gerrit.server.config.PluginConfigFactory;
import com.google.inject.Inject;
import java.io.IOException;
import java.util.Collections;
import java.util.concurrent.ExecutionException;
import org.eclipse.jgit.lib.Config;
import org.junit.Ignore;
import org.testcontainers.containers.GenericContainer;
import org.testcontainers.containers.wait.strategy.Wait;

@Ignore
public class SpannerEmulatorContainer {
  public static class Container extends GenericContainer<Container> {
    public static String EMULATOR_VERSION = "1.5.7";

    public Container() {
      super("gcr.io/cloud-spanner-emulator/emulator:" + EMULATOR_VERSION);
    }
  }

  public static final String PROJECT_ID = "test";
  public static final String SPANNER_INSTANCE_ID = "instance";
  public static final String SPANNER_DATABASE_ID = "refdb";
  private static final int GRPC_PORT = 9010;
  private static final int REST_PORT = 9020;
  private static final String pluginName = "spanner-refdb";

  private final Container container;
  private final Integer grpcPort;
  private final Integer restPort;

  private final Spanner spanner;
  private final InstanceAdminClient instanceAdminClient;
  private final Instance spannerInstance;
  private final Database spannerDatabase;
  private final DatabaseClient databaseClient;
  private final SpannerRefDatabase spannerRefDb;
  private final Configuration pluginConfig;

  @Inject
  @SuppressWarnings("resource")
  public SpannerEmulatorContainer() throws Exception {
    container =
        new Container().withExposedPorts(GRPC_PORT, REST_PORT).waitingFor(Wait.forListeningPort());
    container.start();
    grpcPort = container.getMappedPort(GRPC_PORT);
    restPort = container.getMappedPort(REST_PORT);
    System.out.println(
        "Spanner emulator container started and is listening on ports "
            + grpcPort
            + ", "
            + restPort);

    spanner = getEmulatorOptions().getService();
    instanceAdminClient = spanner.getInstanceAdminClient();
    spannerInstance = createSpannerInstance();
    spannerDatabase =
        spannerInstance.createDatabase(SPANNER_DATABASE_ID, Collections.emptyList()).get();
    pluginConfig = createEmulatorConfiguration();
    createSchema();
    databaseClient = createDatabaseClient();
    spannerRefDb = new SpannerRefDatabase(databaseClient);
  }

  private void createSchema() {
    DatabaseAdminClient dbAdminClient = spanner.getDatabaseAdminClient();
    SpannerLifeCycleManager lcm = new SpannerLifeCycleManager(pluginConfig, dbAdminClient);
    lcm.start();
  }

  public void cleanup() {
    spannerDatabase.drop();
    instanceAdminClient.deleteInstance(SPANNER_INSTANCE_ID);
    spanner.close();
    container.stop();
    container.close();
    System.out.println("Spanner emulator container was stopped");
  }

  public Container getContainer() {
    return container;
  }

  public Integer getGrpcPort() {
    return grpcPort;
  }

  public Integer getRestPort() {
    return restPort;
  }

  public Database getSpannerDatabase() {
    return spannerDatabase;
  }

  public SpannerRefDatabase getSpannerRefDatabase() {
    return spannerRefDb;
  }

  private SpannerOptions getEmulatorOptions() {
    return SpannerOptions.newBuilder()
        .setEmulatorHost("localhost:" + getGrpcPort())
        .setCredentials(NoCredentials.getInstance())
        .setProjectId(PROJECT_ID)
        .build();
  }

  private Instance createSpannerInstance() throws InterruptedException, ExecutionException {
    InstanceConfigId instanceConfig = InstanceConfigId.of(PROJECT_ID, "emulator-config");
    InstanceId instanceId = InstanceId.of(PROJECT_ID, SPANNER_INSTANCE_ID);
    InstanceInfo instanceInfo =
        InstanceInfo.newBuilder(instanceId)
            .setInstanceConfigId(instanceConfig)
            .setNodeCount(1)
            .setDisplayName("test instance")
            .build();
    return instanceAdminClient.createInstance(instanceInfo).get();
  }

  private DatabaseClient createDatabaseClient() {
    return createDatabaseClient(pluginConfig);
  }

  private Configuration createEmulatorConfiguration() throws IOException {
    Config refDbConfig = new Config();
    refDbConfig.setBoolean(Configuration.SECTION, null, "useEmulator", true);
    refDbConfig.setString(SECTION, SUBSECTION, INSTANCE_KEY, SPANNER_INSTANCE_ID);
    refDbConfig.setString(SECTION, SUBSECTION, DATABASE_KEY, SPANNER_DATABASE_ID);

    PluginConfigFactory cfgFactory = mock(PluginConfigFactory.class);
    when(cfgFactory.getGlobalPluginConfig(pluginName)).thenReturn(refDbConfig);
    Configuration spannerConfig = new Configuration(cfgFactory, pluginName);
    spannerConfig.setOptions(getEmulatorOptions());
    return spannerConfig;
  }

  private DatabaseClient createDatabaseClient(Configuration configuration) {
    return configuration.getOptions().getService().getDatabaseClient(configuration.getDatabaseId());
  }
}
