// 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.owners.common;

import com.google.common.cache.RemovalNotification;
import com.google.gerrit.entities.RefNames;
import com.google.gerrit.extensions.annotations.PluginName;
import com.google.gerrit.extensions.events.GitBatchRefUpdateListener;
import com.google.gerrit.extensions.registration.DynamicSet;
import com.google.gerrit.server.cache.CacheModule;
import com.google.gerrit.server.cache.CacheRemovalListener;
import com.google.gerrit.server.config.AllUsersName;
import com.google.inject.Inject;
import com.google.inject.Module;
import com.google.inject.Singleton;
import com.google.inject.TypeLiteral;
import java.util.Objects;
import java.util.Optional;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;

public interface PathOwnersEntriesCache {
  String CACHE_NAME = "path_owners_entries";

  static Module module() {
    return new CacheModule() {
      @Override
      protected void configure() {
        cache(CACHE_NAME, Key.class, new TypeLiteral<Optional<OwnersConfig>>() {});
        bind(PathOwnersEntriesCache.class).to(PathOwnersEntriesCacheImpl.class);
        DynamicSet.bind(binder(), GitBatchRefUpdateListener.class)
            .to(OwnersRefUpdateListener.class);
        DynamicSet.bind(binder(), CacheRemovalListener.class).to(OwnersCacheRemovalListener.class);
      }
    };
  }

  Optional<OwnersConfig> get(
      String project, String branch, String path, Callable<Optional<OwnersConfig>> loader)
      throws ExecutionException;

  void invalidate(String project, String branch);

  void invalidateIndexKey(Key key);

  class Key {
    final String project;
    final String branch;
    final String path;

    Key(String project, String branch, String path) {
      this.project = project;
      this.branch = branch;
      this.path = path;
    }

    @Override
    public int hashCode() {
      return Objects.hash(branch, path, project);
    }

    @Override
    public boolean equals(Object obj) {
      if (this == obj) {
        return true;
      }

      if (obj == null) {
        return false;
      }

      if (getClass() != obj.getClass()) {
        return false;
      }

      Key other = (Key) obj;
      return Objects.equals(branch, other.branch)
          && Objects.equals(path, other.path)
          && Objects.equals(project, other.project);
    }

    @Override
    public String toString() {
      StringBuilder builder = new StringBuilder();
      builder.append("Key [project=");
      builder.append(project);
      builder.append(", branch=");
      builder.append(branch);
      builder.append(", path=");
      builder.append(path);
      builder.append("]");
      return builder.toString();
    }
  }

  @Singleton
  class OwnersRefUpdateListener implements GitBatchRefUpdateListener {
    private final PathOwnersEntriesCache cache;
    private final String allUsersName;

    @Inject
    OwnersRefUpdateListener(PathOwnersEntriesCache cache, AllUsersName allUsersName) {
      this.cache = cache;
      this.allUsersName = allUsersName.get();
    }

    @Override
    public void onGitBatchRefUpdate(GitBatchRefUpdateListener.Event event) {
      String projectName = event.getProjectName();
      if (!allUsersName.equals(projectName)) {
        event.getUpdatedRefs().stream()
            .filter(refUpdate -> supportedEvent(refUpdate.getRefName()))
            .forEach(refUpdate -> cache.invalidate(projectName, refUpdate.getRefName()));
      }
    }

    private boolean supportedEvent(String refName) {
      return (refName.equals(RefNames.REFS_CONFIG) || !RefNames.isGerritRef(refName));
    }
  }

  @Singleton
  class OwnersCacheRemovalListener implements CacheRemovalListener<Key, PathOwnersEntry> {
    private final PathOwnersEntriesCache cache;
    private final String cacheName;

    @Inject
    OwnersCacheRemovalListener(@PluginName String pluginName, PathOwnersEntriesCache cache) {
      this.cache = cache;
      this.cacheName = String.format("%s.%s", pluginName, CACHE_NAME);
    }

    @Override
    public void onRemoval(
        String pluginName,
        String cacheName,
        RemovalNotification<Key, PathOwnersEntry> notification) {
      if (!this.cacheName.equals(cacheName)) {
        return;
      }

      cache.invalidateIndexKey(notification.getKey());
    }
  }
}
