package com.googlesource.gerrit.plugins.quota;

import com.google.common.cache.CacheLoader;
import com.google.common.cache.LoadingCache;
import com.google.gerrit.extensions.registration.DynamicSet;
import com.google.gerrit.reviewdb.client.Project;
import com.google.gerrit.server.cache.CacheModule;
import com.google.gerrit.server.project.ProjectCache;
import com.google.inject.Key;
import com.google.inject.Module;
import com.google.inject.Provides;
import com.google.inject.Singleton;
import com.google.inject.TypeLiteral;
import com.google.inject.name.Named;
import com.google.inject.name.Names;

import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicLong;

class PersistentCounter {
  public static final String FETCH = "FETCH_COUNTS";
  public static final String PUSH = "PUSH_COUNTS";

  static Module module() {
    return new CacheModule() {
      protected void configure() {
        persist(FETCH, Project.NameKey.class, AtomicLong.class).loader(
            Loader.class).expireAfterWrite(Integer.MAX_VALUE, TimeUnit.DAYS);
        persist(PUSH, Project.NameKey.class, AtomicLong.class).loader(
            Loader.class).expireAfterWrite(Integer.MAX_VALUE, TimeUnit.DAYS);
        DynamicSet.bind(binder(), UsageDataEventCreator.class).to(creatorKey(FETCH));
        DynamicSet.bind(binder(), UsageDataEventCreator.class).to(creatorKey(PUSH));
        DynamicSet.bind(binder(), UsageDataEventCreator.class).to(RepoSizeEventCreator.class);
      }

      private Key<UsageDataEventCreator> creatorKey(String kind) {
        Key<UsageDataEventCreator> pushCreatorKey =
            Key.get(new TypeLiteral<UsageDataEventCreator>() {},
                Names.named(kind));
        return pushCreatorKey;
      }

      @Provides @Singleton @Named(FETCH)
      PersistentCounter provideFetchCounter(
          @Named(FETCH) LoadingCache<Project.NameKey, AtomicLong> counts) {
        return new PersistentCounter(counts);
      }

      @Provides @Singleton @Named(PUSH)
      PersistentCounter providePushCounter(
          @Named(PUSH) LoadingCache<Project.NameKey, AtomicLong> counts) {
        return new PersistentCounter(counts);
      }

      @Provides @Singleton @Named(FETCH)
      UsageDataEventCreator provideFetchEventCreator(ProjectCache projectCache,
          @Named(FETCH) PersistentCounter counts) {
        return new FetchAndPushEventCreator(projectCache, counts, FetchAndPushEventCreator.FETCH_COUNT);
      }

      @Provides @Singleton @Named(PUSH)
      UsageDataEventCreator providePushEventCreator(ProjectCache projectCache,
          @Named(PUSH) PersistentCounter counts) {
        return new FetchAndPushEventCreator(projectCache, counts, FetchAndPushEventCreator.PUSH_COUNT);
      }
    };
  }

  private final LoadingCache<Project.NameKey, AtomicLong> counts;

  PersistentCounter(LoadingCache<Project.NameKey, AtomicLong> counts) {
    this.counts = counts;
  }

  long getAndReset(Project.NameKey p) {
    AtomicLong count = counts.getIfPresent(p);
    if (count != null) {
      return count.getAndSet(0);
    } else {
      return 0;
    }
  }

  void increment(Project.NameKey p) {
    counts.getUnchecked(p).incrementAndGet();
  }

  @Singleton
  private static class Loader extends CacheLoader<Project.NameKey, AtomicLong> {

    @Override
    public AtomicLong load(Project.NameKey project) {
      return new AtomicLong(0);
    }
  }

}
