// Copyright (C) 2011 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.google.gerrit.server.git;

package com.google.gerrit.server.git;

import com.google.common.cache.Cache;
import com.google.gerrit.reviewdb.client.Project;
import com.google.gerrit.server.cache.CacheModule;
import com.google.inject.Inject;
import com.google.inject.Module;
import com.google.inject.Singleton;
import com.google.inject.name.Named;

import org.eclipse.jgit.lib.ObjectId;

import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;

@Singleton
public class TagCache {
  private static final String CACHE_NAME = "git_tags";

  public static Module module() {
    return new CacheModule() {
      @Override
      protected void configure() {
        persist(CACHE_NAME, String.class, EntryVal.class);
        bind(TagCache.class);
      }
    };
  }

  private final Cache<String, EntryVal> cache;
  private final Object createLock = new Object();

  @Inject
  TagCache(@Named(CACHE_NAME) Cache<String, EntryVal> cache) {
    this.cache = cache;
  }

  /**
   * Advise the cache that a reference fast-forwarded.
   * <p>
   * This operation is not necessary, the cache will automatically detect changes
   * made to references and update itself on demand. However, this method may
   * allow the cache to update more quickly and reuse the caller's computation of
   * the fast-forward status of a branch.
   *
   * @param name project the branch is contained in.
   * @param refName the branch name.
   * @param oldValue the old value, before the fast-forward. The cache
   *        will only update itself if it is still using this old value.
   * @param newValue the current value, after the fast-forward.
   */
  public void updateFastForward(Project.NameKey name, String refName,
      ObjectId oldValue, ObjectId newValue) {
    // Be really paranoid and null check everything. This method should
    // never fail with an exception. Some of these references can be null
    // (e.g. not all projects are cached, or the cache is not current).
    //
    EntryVal val = cache.getIfPresent(name.get());
    if (val != null) {
      TagSetHolder holder = val.holder;
      if (holder != null) {
        TagSet tags = holder.getTagSet();
        if (tags != null) {
          if (tags.updateFastForward(refName, oldValue, newValue)) {
            cache.put(name.get(), val);
          }
        }
      }
    }
  }

  TagSetHolder get(Project.NameKey name) {
    EntryVal val = cache.getIfPresent(name.get());
    if (val == null) {
      synchronized (createLock) {
        val = cache.getIfPresent(name.get());
        if (val == null) {
          val = new EntryVal();
          val.holder = new TagSetHolder(name);
          cache.put(name.get(), val);
        }
      }
    }
    return val.holder;
  }

  void put(Project.NameKey name, TagSetHolder tags) {
    EntryVal val = new EntryVal();
    val.holder = tags;
    cache.put(name.get(), val);
  }

  static class EntryVal implements Serializable {
    static final long serialVersionUID = 1L;

    transient TagSetHolder holder;

    private void readObject(ObjectInputStream in) throws IOException,
        ClassNotFoundException {
      holder = new TagSetHolder(new Project.NameKey(in.readUTF()));
      if (in.readBoolean()) {
        TagSet tags = new TagSet(holder.getProjectName());
        tags.readObject(in);
        holder.setTagSet(tags);
      }
    }

    private void writeObject(ObjectOutputStream out) throws IOException {
      TagSet tags = holder.getTagSet();
      out.writeUTF(holder.getProjectName().get());
      out.writeBoolean(tags != null);
      if (tags != null) {
        tags.writeObject(out);
      }
    }
  }
}
