// 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 com.google.cloud.NoCredentials;
import com.google.cloud.spanner.Database;
import com.google.cloud.spanner.DatabaseClient;
import com.google.cloud.spanner.DatabaseId;
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 java.util.Collections;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ScheduledThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import org.testcontainers.containers.SpannerEmulatorContainer;
import org.testcontainers.utility.DockerImageName;

public class EmulatedSpannerRefDb extends SpannerTestSystem {
  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 final SpannerEmulatorContainer container;

  private final Spanner spanner;
  private final SpannerOptions spannerOptions;
  private final InstanceAdminClient instanceAdminClient;
  private final Instance spannerInstance;
  private final Database spannerDatabase;
  private final DatabaseId dbId;
  private final DatabaseClient databaseClient;
  private final ScheduledThreadPoolExecutor heartbeatExecutor;
  private final SpannerRefDatabase spannerRefDb;

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

    spannerOptions = getEmulatorOptions();
    spanner = spannerOptions.getService();
    instanceAdminClient = spanner.getInstanceAdminClient();
    spannerInstance = createSpannerInstance();
    dbId = DatabaseId.of(spannerOptions.getProjectId(), SPANNER_INSTANCE_ID, SPANNER_DATABASE_ID);
    spannerDatabase =
        spannerInstance.createDatabase(SPANNER_DATABASE_ID, Collections.emptyList()).get();
    createSchema();
    databaseClient = createDatabaseClient();
    heartbeatExecutor = new ScheduledThreadPoolExecutor(2);
    Lock.Factory lockFactory =
        new Lock.Factory() {
          @Override
          public Lock create(String projectName, String refName) {
            return new Lock(databaseClient, "", heartbeatExecutor, projectName, refName);
          }
        };
    spannerRefDb = new SpannerRefDatabase(databaseClient, lockFactory);
  }

  @Override
  void reset() throws Exception {
    // do nothing, a new container is created for each instance of this class
  }

  @Override
  SpannerRefDatabase database() {
    return spannerRefDb;
  }

  @Override
  DatabaseClient dbClient() {
    return databaseClient;
  }

  @Override
  ScheduledThreadPoolExecutor heartbeatExecutor() {
    return heartbeatExecutor;
  }

  @Override
  public void cleanup() {
    heartbeatExecutor.shutdownNow();
    try {
      heartbeatExecutor.awaitTermination(Long.MAX_VALUE, TimeUnit.SECONDS);
    } catch (InterruptedException e) {
      throw new RuntimeException(e);
    }
    spannerDatabase.drop();
    instanceAdminClient.deleteInstance(SPANNER_INSTANCE_ID);
    spanner.close();
    container.stop();
    container.close();
    System.out.println("Spanner emulator container was stopped");
  }

  private void createSchema() {
    DatabaseSchemaCreator dsc =
        new DatabaseSchemaCreator(spannerOptions.getService().getDatabaseAdminClient(), dbId);
    dsc.start();
  }

  public SpannerEmulatorContainer getContainer() {
    return container;
  }

  public Database getSpannerDatabase() {
    return spannerDatabase;
  }

  public SpannerRefDatabase getSpannerRefDatabase() {
    return spannerRefDb;
  }

  public DatabaseClient getDatabaseClient() {
    return databaseClient;
  }

  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 spannerOptions.getService().getDatabaseClient(dbId);
  }
}
