// 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.EMULATOR_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 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.SpannerEmulatorContainer;
import org.testcontainers.utility.DockerImageName;

@Ignore
public class EmulatedSpannerRefDb {
  public static final String PROJECT_ID = "test";
  public static final String SPANNER_INSTANCE_ID = "spanner-instance";
  public static final String SPANNER_DATABASE_ID = "global-refdb";
  private static final String pluginName = "spanner-refdb";

  private final SpannerEmulatorContainer container;

  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;

  public EmulatedSpannerRefDb() throws Exception {
    container =
        new SpannerEmulatorContainer(
            DockerImageName.parse("gcr.io/cloud-spanner-emulator/emulator").withTag("1.5.9"));
    container.start();
    System.out.println(
        String.format(
            "Spanner emulator container started and is listening on %s",
            container.getEmulatorGrpcEndpoint()));

    spanner = getEmulatorOptions().getService();
    instanceAdminClient = spanner.getInstanceAdminClient();
    spannerInstance = createSpannerInstance();
    spannerDatabase =
        spannerInstance.createDatabase(SPANNER_DATABASE_ID, Collections.emptyList()).get();
    pluginConfig = createEmulatorConfiguration();
    createSchema();
    databaseClient = createDatabaseClient();
    Lock.LockFactory lockFactory =
        new Lock.LockFactory() {
          @Override
          public Lock create(String projectName, String refName) {
            return new Lock(databaseClient, "", projectName, refName);
          }
        };
    spannerRefDb = new SpannerRefDatabase(databaseClient, lockFactory);
  }

  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 SpannerEmulatorContainer getContainer() {
    return container;
  }

  public Database getSpannerDatabase() {
    return spannerDatabase;
  }

  public SpannerRefDatabase getSpannerRefDatabase() {
    return spannerRefDb;
  }

  private SpannerOptions getEmulatorOptions() {
    return SpannerOptions.newBuilder()
        .setEmulatorHost(container.getEmulatorGrpcEndpoint())
        .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.setString(SECTION, SUBSECTION, INSTANCE_KEY, SPANNER_INSTANCE_ID);
    refDbConfig.setString(SECTION, SUBSECTION, DATABASE_KEY, SPANNER_DATABASE_ID);
    refDbConfig.setBoolean(SECTION, SUBSECTION, EMULATOR_KEY, true);

    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());
  }
}
