// Copyright (C) 2025 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.

import com.google.common.flogger.FluentLogger
import com.google.gerrit.entities.Project
import com.google.gerrit.extensions.annotations.*
import com.google.gerrit.extensions.events.LifecycleListener
import com.google.gerrit.lifecycle.LifecycleModule
import com.google.gerrit.metrics.*
import com.google.gerrit.server.config.*
import com.google.gerrit.server.git.LocalDiskRepositoryManager
import com.google.inject.Singleton
import org.eclipse.jgit.lib.Constants

import javax.inject.Inject
import java.util.concurrent.TimeUnit

import static groovy.io.FileType.FILES

@Singleton
@Listen
class RepoRepackTracker implements LifecycleListener {

  private static final FluentLogger logger = FluentLogger.forEnclosingClass()
  private static final DESCRIPTION_GC = "Check gc running for the project"
  private static final DESCRIPTION_REPACK = "Check repack running for the project"
  private static final NAME_GC = "is_gc_running_per_project"
  private static final NAME_REPACK = "is_repack_running_per_project"
  private static final GC_PID_FILE = "gc.pid"
  private static final GIT_PACK_FOLDER = "objects/pack"
  private static final TMP_PREFIX = "tmp_"
  private static final TMP_SUFFIX = ".tmp"

  @Inject
  @PluginName
  String pluginName
  @Inject
  PluginConfigFactory configFactory
  @Inject
  MetricMaker metrics
  @Inject
  LocalDiskRepositoryManager repoMgr

  private def tmpFilter = ~/^(${TMP_PREFIX}.*|.*${TMP_SUFFIX})$/
  private long repackStalenessAfterMs
  private long gcStalenessAfterMs
  CallbackMetric1<String, Long> callbackMetricGc
  CallbackMetric1<String, Long> callbackMetricRepack
  List<String> projects

  @Override
  void start() {
    PluginConfig pluginConfig = configFactory.getFromGerritConfig(pluginName)
    long repackStalenessAfter = ConfigUtil.getTimeUnit(
        pluginConfig.getString("considerRepackStaleAfter", "60 minutes"),
        60L,
        TimeUnit.MINUTES)
    long gcStalenessAfter = ConfigUtil.getTimeUnit(
        pluginConfig.getString("considerGcStaleAfter", "720 minutes"),
        720L,
        TimeUnit.MINUTES)
    repackStalenessAfterMs = TimeUnit.MILLISECONDS.convert(repackStalenessAfter, TimeUnit.MINUTES)
    gcStalenessAfterMs = TimeUnit.MILLISECONDS.convert(gcStalenessAfter, TimeUnit.MINUTES)

    projects = pluginConfig.getStringList("project")

    callbackMetricGc = createCallbackMetric(NAME_GC, DESCRIPTION_GC)
    callbackMetricRepack = createCallbackMetric(NAME_REPACK, DESCRIPTION_REPACK)
    addMetricsTriggers()

    logger.atInfo().log("Plugin %s started for %d projects (considering gc stale after %d minutes, repack after %d minutes)",
        pluginName,
        projects.size(),
        gcStalenessAfter,
        repackStalenessAfter)
  }

  CallbackMetric1<String, Long> createCallbackMetric(String name, String description) {
    metrics.newCallbackMetric(
        name,
        Long.class,
        new Description(description).setGauge(),
        Field.ofProjectName("repository_name")
            .description(description)
            .build()
    )
  }

  void addMetricsTriggers() {
    metrics.newTrigger(
        callbackMetricRepack, {
      if (projects.isEmpty()) {
        callbackMetricRepack.forceCreate("")
      } else {
        projects.each { e ->
          callbackMetricRepack.set(e, checkRepackingRunningForProject(e))
        }
        callbackMetricRepack.prune()
      }
    })
    metrics.newTrigger(
        callbackMetricGc, {
      if (projects.isEmpty()) {
        callbackMetricGc.forceCreate("")
      } else {
        projects.each { e ->
          callbackMetricGc.set(e, checkGCRunningForProject(e))
        }
        callbackMetricGc.prune()
      }
    })
  }

  long checkGCRunningForProject(String projectName) {
    def isGcRunning = 0L
    try {
      def repoDir = getRepoDir(projectName)
      def gcPid = new File(repoDir, GC_PID_FILE)
      isGcRunning = (gcPid.exists() && !isFileStale(gcPid))? 1L : 0L
    } catch (Exception e) {
      logger.atSevere().withCause(e).log("Could not check project %s",  projectName)
    }
    isGcRunning
  }

  long checkRepackingRunningForProject(String projectName) {
    def isRepackRunning = 0L
    try {
      def repoDir = getRepoDir(projectName)
      def packDir = new File(repoDir, GIT_PACK_FOLDER)
      if (packDir.exists() && hasRepackTmpFiles(packDir)) {
        isRepackRunning = 1L
      }
    } catch (Exception e) {
      logger.atSevere().withCause(e).log("Could not check project %s",  projectName)
    }
    isRepackRunning
  }

  File getRepoDir(String projectName) {
    def name = Project.nameKey(projectName)
    def path = repoMgr.getBasePath(name)
    return path.resolve("${name.get()}${Constants.DOT_GIT_EXT}").toFile()
  }

  boolean hasRepackTmpFiles(folder) {
    def modifiedCutoffTime = System.currentTimeMillis() - repackStalenessAfterMs
    def tmpFileFound = false

    folder.traverse(type: FILES, nameFilter: tmpFilter) { file ->
      if (file.lastModified() >= modifiedCutoffTime) {
        tmpFileFound = true
      }
    }
    return tmpFileFound
  }

  boolean isFileStale(File f) {
    def fileExpiry = f.lastModified() + gcStalenessAfterMs
    return System.currentTimeMillis() > fileExpiry
  }

  @Override
  void stop() {}
}

class RepoRepackTrackerModule extends LifecycleModule {
    protected void configure() {
        listener().to(RepoRepackTracker)
    }
}

modules = [RepoRepackTrackerModule]
