// Copyright (C) 2019 GerritForge Ltd
//
// 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.gerritforge.gerrit.globalrefdb;

import com.google.common.collect.MapMaker;
import com.google.gerrit.reviewdb.client.Project;
import java.util.Optional;
import java.util.concurrent.ConcurrentMap;
import java.util.concurrent.atomic.AtomicReference;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
import org.eclipse.jgit.lib.ObjectId;
import org.eclipse.jgit.lib.Ref;
import org.junit.Ignore;

@Ignore
public class FakeGlobalRefDatabase implements GlobalRefDatabase {

  private ConcurrentMap<Project.NameKey, ConcurrentMap<String, AtomicReference<ObjectId>>>
      keyValueStore;
  private ConcurrentMap<String, AtomicReference<?>> genericKeyValueStore;

  private ConcurrentMap<Project.NameKey, ConcurrentMap<String, AtomicReference<Lock>>> refLockStore;

  public FakeGlobalRefDatabase() {
    keyValueStore = new MapMaker().concurrencyLevel(1).makeMap();
    refLockStore = new MapMaker().concurrencyLevel(1).makeMap();
    genericKeyValueStore = new MapMaker().concurrencyLevel(1).makeMap();
  }

  @Override
  public boolean isUpToDate(Project.NameKey project, Ref ref) throws GlobalRefDbLockException {
    AtomicReference<ObjectId> value = projectRefDb(project).get(ref.getName());
    if (value == null) {
      return true;
    }
    return ref.getObjectId().equals(value.get());
  }

  @Override
  public boolean compareAndPut(Project.NameKey project, Ref currRef, ObjectId newRefValue)
      throws GlobalRefDbSystemError {
    ConcurrentMap<String, AtomicReference<ObjectId>> projectRefDb = projectRefDb(project);
    AtomicReference<ObjectId> currValue = projectRefDb.get(currRef.getName());
    if (currValue == null) {
      projectRefDb.put(currRef.getName(), new AtomicReference<>(newRefValue));
      return true;
    }

    return currValue.compareAndSet(currRef.getObjectId(), newRefValue);
  }

  @Override
  @SuppressWarnings("unchecked")
  public <T> boolean compareAndPut(Project.NameKey project, String refName, T currValue, T newValue)
      throws GlobalRefDbSystemError {
    String key = String.format("%s/%s", project.get(), refName);
    AtomicReference<T> storedValue = (AtomicReference<T>) genericKeyValueStore.get(key);
    if (storedValue == null) {
      genericKeyValueStore.put(key, new AtomicReference<>(newValue));
      return true;
    }

    return storedValue.compareAndSet(currValue, newValue);
  }

  @Override
  public AutoCloseable lockRef(Project.NameKey project, String refName)
      throws GlobalRefDbLockException {
    ConcurrentMap<String, AtomicReference<Lock>> projectRefLock = projectRefLock(project);
    AtomicReference<Lock> currLock = projectRefLock.get(refName);
    if (currLock == null) {
      Lock lock = new ReentrantLock();
      lock.lock();
      projectRefLock.put(refName, new AtomicReference<>(lock));
      return new RefLock(lock);
    }

    Lock lock = currLock.get();
    lock.lock();
    return new RefLock(lock);
  }

  @Override
  public boolean exists(Project.NameKey project, String refName) {
    return projectRefDb(project).containsKey(refName);
  }

  @Override
  public void remove(Project.NameKey project) throws GlobalRefDbSystemError {
    keyValueStore.remove(project);
  }

  @Override
  @SuppressWarnings("unchecked")
  public <T> Optional<T> get(Project.NameKey project, String refName, Class<T> clazz)
      throws GlobalRefDbSystemError {
    String key = String.format("%s/%s", project.get(), refName);
    return Optional.ofNullable((T) genericKeyValueStore.get(key))
        .map(v -> ((AtomicReference<T>) v).get());
  }

  private ConcurrentMap<String, AtomicReference<ObjectId>> projectRefDb(Project.NameKey project) {
    ConcurrentMap<String, AtomicReference<ObjectId>> projectRefDb = keyValueStore.get(project);
    if (projectRefDb == null) {
      projectRefDb = new MapMaker().concurrencyLevel(1).makeMap();
      keyValueStore.put(project, projectRefDb);
    }

    return projectRefDb;
  }

  private ConcurrentMap<String, AtomicReference<Lock>> projectRefLock(Project.NameKey project) {
    ConcurrentMap<String, AtomicReference<Lock>> projectRefLock = refLockStore.get(project);
    if (projectRefLock == null) {
      projectRefLock = new MapMaker().concurrencyLevel(1).makeMap();
      refLockStore.put(project, projectRefLock);
    }

    return projectRefLock;
  }

  private static class RefLock implements AutoCloseable {
    private Lock lock;

    public RefLock(Lock lock) {
      this.lock = lock;
    }

    @Override
    public void close() throws Exception {
      lock.unlock();
    }
  }
}
