// 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.auth.oauth2.GoogleCredentials;
import com.google.cloud.spanner.DatabaseId;
import com.google.cloud.spanner.SpannerOptions;
import com.google.common.base.Strings;
import com.google.common.flogger.FluentLogger;
import com.google.gerrit.extensions.annotations.PluginName;
import com.google.gerrit.server.config.PluginConfigFactory;
import com.google.inject.Inject;
import com.google.inject.Singleton;
import java.io.FileInputStream;
import java.io.IOException;
import org.eclipse.jgit.lib.Config;

@Singleton
class Configuration {
  private static final FluentLogger logger = FluentLogger.forEnclosingClass();

  public static final String DATABASE_KEY = "database";
  public static final String INSTANCE_KEY = "instance";
  public static final String EMULATOR_KEY = "useEmulator";
  public static final String CREDENTIALS_KEY = "credentialsPath";
  public static final String SECTION = "ref-database";
  public static final String SUBSECTION = "spanner";
  private final String spannerInstance;
  private final String spannerDatabase;
  private SpannerOptions options;

  @Inject
  Configuration(PluginConfigFactory configFactory, @PluginName String pluginName)
      throws IOException {
    Config cfg = configFactory.getGlobalPluginConfig(pluginName);
    this.spannerInstance = getString(cfg, SECTION, SUBSECTION, INSTANCE_KEY, "spanner-instance");
    this.spannerDatabase = getString(cfg, SECTION, SUBSECTION, DATABASE_KEY, "global-refdb");
    boolean useEmulator = cfg.getBoolean(SECTION, SUBSECTION, EMULATOR_KEY, false);
    if (useEmulator) {
      this.options = SpannerOptions.newBuilder().build();
      logger.atInfo().log(
          "Using local Spanner emulator for global-refdb; Spanner credentials will not be read.");
    } else {
      String credentialsPath = getString(cfg, SECTION, SUBSECTION, CREDENTIALS_KEY, null);
      GoogleCredentials credentials =
          GoogleCredentials.fromStream(new FileInputStream(credentialsPath));
      this.options = SpannerOptions.newBuilder().setCredentials(credentials).build();
    }
  }

  final DatabaseId getDatabaseId() {
    return DatabaseId.of(options.getProjectId(), spannerInstance, spannerDatabase);
  }

  final SpannerOptions getOptions() {
    return options;
  }

  void setOptions(SpannerOptions options) {
    this.options = options;
  }

  private String getString(
      Config cfg, String section, String subsection, String name, String defaultValue) {
    String value = cfg.getString(section, subsection, name);
    if (!Strings.isNullOrEmpty(value)) {
      return value;
    }
    return defaultValue;
  }
}
