// Copyright 2012 Google Inc. All Rights Reserved.
//
// 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.gitiles;

import com.google.common.base.Throwables;
import com.google.common.cache.Cache;
import com.google.common.cache.CacheBuilder;
import java.io.IOException;
import java.util.concurrent.ExecutionException;
import org.eclipse.jgit.lib.Constants;
import org.eclipse.jgit.lib.ObjectId;
import org.eclipse.jgit.lib.PersonIdent;
import org.eclipse.jgit.revwalk.RevCommit;
import org.eclipse.jgit.revwalk.RevObject;
import org.eclipse.jgit.revwalk.RevTag;
import org.eclipse.jgit.revwalk.RevWalk;

/**
 * Cache of the time associated with Git objects.
 *
 * <p>Uses the time as stored in annotated tags if available, or else the commit time of the tagged
 * commit. Non-commits are given {@link Long#MIN_VALUE}, rather than searching for occurrences in
 * the entire repository.
 */
public class TimeCache {
  public static CacheBuilder<Object, Object> defaultBuilder() {
    return CacheBuilder.newBuilder().maximumSize(10 << 10);
  }

  private final Cache<ObjectId, Long> cache;

  public TimeCache() {
    this(defaultBuilder());
  }

  public TimeCache(CacheBuilder<Object, Object> builder) {
    this.cache = builder.build();
  }

  public Cache<?, ?> getCache() {
    return cache;
  }

  Long getTime(final RevWalk walk, final ObjectId id) throws IOException {
    try {
      return cache.get(
          id,
          () -> {
            RevObject o = walk.parseAny(id);
            while (o instanceof RevTag) {
              walk.parseBody(o);

              RevTag tag = (RevTag) o;
              PersonIdent ident = tag.getTaggerIdent();
              if (ident != null) {
                return ident.getWhen().getTime() / 1000;
              }
              o = tag.getObject();
              walk.parseHeaders(o);
            }
            if (o.getType() == Constants.OBJ_COMMIT) {
              return Long.valueOf(((RevCommit) o).getCommitTime());
            }
            return Long.MIN_VALUE;
          });
    } catch (ExecutionException e) {
      Throwables.throwIfInstanceOf(e.getCause(), IOException.class);
      throw new IOException(e);
    }
  }
}
