// 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 static com.google.common.truth.Truth.assertThat;
import static org.eclipse.jgit.lib.Constants.OBJ_BLOB;
import static org.eclipse.jgit.lib.Constants.OBJ_COMMIT;
import static org.eclipse.jgit.lib.Constants.OBJ_TAG;

import com.google.common.cache.CacheBuilder;
import com.google.gitiles.RevisionParser.Result;

import org.eclipse.jgit.internal.storage.dfs.DfsRepository;
import org.eclipse.jgit.internal.storage.dfs.DfsRepositoryDescription;
import org.eclipse.jgit.internal.storage.dfs.InMemoryRepository;
import org.eclipse.jgit.junit.TestRepository;
import org.eclipse.jgit.revwalk.RevBlob;
import org.eclipse.jgit.revwalk.RevCommit;
import org.eclipse.jgit.revwalk.RevTag;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;

/** Tests for the revision parser. */
@RunWith(JUnit4.class)
public class RevisionParserTest {
  private TestRepository<DfsRepository> repo;
  private RevisionParser parser;

  @Before
  public void setUp() throws Exception {
    repo = new TestRepository<DfsRepository>(
        new InMemoryRepository(new DfsRepositoryDescription("test")));
    parser = new RevisionParser(
        repo.getRepository(),
        new TestGitilesAccess(repo.getRepository()).forRequest(null),
        new VisibilityCache(false, CacheBuilder.newBuilder().maximumSize(0)));
  }

  @Test
  public void parseRef() throws Exception {
    RevCommit master = repo.branch("refs/heads/master").commit().create();
    assertThat(parser.parse("master"))
        .isEqualTo(new Result(Revision.peeled("master", master)));
    assertThat(parser.parse("refs/heads/master"))
        .isEqualTo(new Result(Revision.peeled("refs/heads/master", master)));
    assertThat(parser.parse("refs//heads//master")).isNull();
    assertThat(parser.parse("refs heads master")).isNull();
  }

  @Test
  public void parseRefParentExpression() throws Exception {
    RevCommit root = repo.commit().create();
    RevCommit parent1 = repo.commit().parent(root).create();
    RevCommit parent2 = repo.commit().parent(root).create();
    RevCommit merge = repo.branch("master").commit()
        .parent(parent1)
        .parent(parent2)
        .create();
    assertThat(parser.parse("master")).isEqualTo(new Result(Revision.peeled("master", merge)));
    assertThat(parser.parse("master^")).isEqualTo(new Result(Revision.peeled("master^", parent1)));
    assertThat(parser.parse("master~1"))
        .isEqualTo(new Result(Revision.peeled("master~1", parent1)));
    assertThat(parser.parse("master^2"))
        .isEqualTo(new Result(Revision.peeled("master^2", parent2)));
    assertThat(parser.parse("master^3")).isNull();
    assertThat(parser.parse("master~2")).isEqualTo(new Result(Revision.peeled("master~2", root)));
  }

  @Test
  public void parseCommitShaVisibleFromHead() throws Exception {
    RevCommit parent = repo.commit().create();
    RevCommit commit = repo.branch("master").commit().parent(parent).create();
    assertThat(parser.parse(commit.name()))
        .isEqualTo(new Result(Revision.peeled(commit.name(), commit)));
    assertThat(parser.parse(parent.name()))
        .isEqualTo(new Result(Revision.peeled(parent.name(), parent)));

    String abbrev = commit.name().substring(0, 6);
    assertThat(parser.parse(abbrev)).isEqualTo(new Result(Revision.peeled(abbrev, commit)));
  }

  @Test
  public void parseCommitShaVisibleFromTag() throws Exception {
    RevCommit parent = repo.commit().create();
    RevCommit commit = repo.commit().parent(parent).create();
    repo.branch("master").commit().create();
    repo.update("refs/tags/tag", repo.tag("tag", commit));

    assertThat(parser.parse(commit.name()))
        .isEqualTo(new Result(Revision.peeled(commit.name(), commit)));
    assertThat(parser.parse(parent.name()))
        .isEqualTo(new Result(Revision.peeled(parent.name(), parent)));
  }

  @Test
  public void parseCommitShaVisibleFromOther() throws Exception {
    RevCommit parent = repo.commit().create();
    RevCommit commit = repo.commit().parent(parent).create();
    repo.branch("master").commit().create();
    repo.update("refs/tags/tag", repo.tag("tag", repo.commit().create()));
    repo.update("refs/meta/config", commit);

    assertThat(parser.parse(commit.name()))
        .isEqualTo(new Result(Revision.peeled(commit.name(), commit)));
    assertThat(parser.parse(parent.name()))
        .isEqualTo(new Result(Revision.peeled(parent.name(), parent)));
  }

  @Test
  public void parseCommitShaVisibleFromChange() throws Exception {
    RevCommit parent = repo.commit().create();
    RevCommit commit = repo.commit().parent(parent).create();
    repo.branch("master").commit().create();
    repo.update("refs/changes/01/0001", commit);

    // Matches exactly.
    assertThat(parser.parse(commit.name()))
        .isEqualTo(new Result(Revision.peeled(commit.name(), commit)));
    // refs/changes/* is excluded from ancestry search.
    assertThat(parser.parse(parent.name())).isNull();
  }

  @Test
  public void parseNonVisibleCommitSha() throws Exception {
    RevCommit other = repo.commit().create();
    repo.branch("master").commit().create();
    assertThat(parser.parse(other.name())).isNull();

    repo.branch("other").update(other);
    assertThat(parser.parse(other.name()))
        .isEqualTo(new Result(Revision.peeled(other.name(), other)));
  }

  @Test
  public void parseDiffRevisions() throws Exception {
    RevCommit parent = repo.commit().create();
    RevCommit commit = repo.branch("master").commit().parent(parent).create();
    RevCommit other = repo.branch("other").commit().create();

    assertThat(parser.parse("master^..master")).isEqualTo(
        new Result(
            Revision.peeled("master", commit),
            Revision.peeled("master^", parent),
            ""));
    assertThat(parser.parse("master^..master/")).isEqualTo(
        new Result(
            Revision.peeled("master", commit),
            Revision.peeled("master^", parent),
            "/"));
    assertThat(parser.parse("master^..master/path/to/a/file")).isEqualTo(
        new Result(
            Revision.peeled("master", commit),
            Revision.peeled("master^", parent),
            "/path/to/a/file"));
    assertThat(parser.parse("master^..master/path/to/a/..file")).isEqualTo(
        new Result(
            Revision.peeled("master", commit),
            Revision.peeled("master^", parent),
            "/path/to/a/..file"));
    assertThat(parser.parse("refs/heads/master^..refs/heads/master")).isEqualTo(
        new Result(
            Revision.peeled("refs/heads/master", commit),
            Revision.peeled("refs/heads/master^", parent),
            ""));
    assertThat(parser.parse("master~1..master")).isEqualTo(
        new Result(
            Revision.peeled("master", commit),
            Revision.peeled("master~1", parent),
            ""));
    // TODO(dborowitz): 2a2362fbb in JGit causes master~2 to resolve to master
    // rather than null. Uncomment when upstream regression is fixed.
    //assertThat(parser.parse("master~2..master")).isNull();
    assertThat(parser.parse("other..master")).isEqualTo(
        new Result(
            Revision.peeled("master", commit),
            Revision.peeled("other", other),
            ""));
  }

  @Test
  public void parseFirstParentExpression() throws Exception {
    RevCommit parent = repo.commit().create();
    RevCommit commit = repo.branch("master").commit().parent(parent).create();

    assertThat(parser.parse("master^!")).isEqualTo(
        new Result(
            Revision.peeled("master", commit),
            Revision.peeled("master^", parent),
            ""));
    assertThat(parser.parse("master^^!")).isEqualTo(
        new Result(
            Revision.peeled("master^", parent),
            Revision.NULL,
            ""));
    assertThat(parser.parse(parent.name() + "^!")).isEqualTo(
        new Result(
            Revision.peeled(parent.name(), parent),
            Revision.NULL,
            ""));

    repo.update("refs/tags/tag", repo.tag("tag", commit));
    assertThat(parser.parse("tag^!")).isEqualTo(
        new Result(
            Revision.peeled("tag", commit),
            Revision.peeled("tag^", parent),
            ""));
    assertThat(parser.parse("tag^^!")).isEqualTo(
        new Result(
            Revision.peeled("tag^", parent),
            Revision.NULL,
            ""));
  }

  @Test
  public void nonVisibleDiffShas() throws Exception {
    RevCommit other = repo.commit().create();
    RevCommit master = repo.branch("master").commit().create();
    assertThat(parser.parse("other..master")).isNull();
    assertThat(parser.parse("master..other")).isNull();

    repo.branch("other").update(other);
    assertThat(parser.parse("other..master")).isEqualTo(
        new Result(
            Revision.peeled("master", master),
            Revision.peeled("other", other),
            ""));
    assertThat(parser.parse("master..other")).isEqualTo(
        new Result(
            Revision.peeled("other", other),
            Revision.peeled("master", master),
            ""));
  }

  @Test
  public void parseTag() throws Exception {
    RevCommit master = repo.branch("master").commit().create();
    RevTag masterTag = repo.update("refs/tags/master-tag", repo.tag("master-tag", master));
    RevTag masterTagTag = repo.update("refs/tags/master-tag-tag",
        repo.tag("master-tag-tag", master));

    assertThat(parser.parse("master-tag")).isEqualTo(
        new Result(new Revision("master-tag", masterTag, OBJ_TAG, master, OBJ_COMMIT)));
    assertThat(parser.parse("master-tag-tag")).isEqualTo(
        new Result(new Revision("master-tag-tag", masterTagTag, OBJ_TAG, master, OBJ_COMMIT)));

    RevBlob blob = repo.update("refs/tags/blob", repo.blob("blob"));
    RevTag blobTag = repo.update("refs/tags/blob-tag", repo.tag("blob-tag", blob));
    assertThat(parser.parse("blob")).isEqualTo(new Result(Revision.peeled("blob", blob)));
    assertThat(parser.parse("blob-tag"))
        .isEqualTo(new Result(new Revision("blob-tag", blobTag, OBJ_TAG, blob, OBJ_BLOB)));
  }

  @Test
  public void parseUnsupportedRevisionExpressions() throws Exception {
    RevBlob blob = repo.blob("blob contents");
    RevCommit master = repo.branch("master").commit().add("blob", blob).create();

    assertThat(repo.getRepository().resolve("master^{}")).isEqualTo(master);
    assertThat(parser.parse("master^{}")).isNull();

    assertThat(repo.getRepository().resolve("master^{commit}")).isEqualTo(master);
    assertThat(parser.parse("master^{commit}")).isNull();

    assertThat(repo.getRepository().resolve("master:blob")).isEqualTo(blob);
    assertThat(parser.parse("master:blob")).isNull();

    // TestRepository has no simple way of setting the reflog.
    //assertThat(repo.getRepository().resolve("master@{0}")).isEqualTo(null);
    assertThat(parser.parse("master@{0}")).isNull();
  }

  @Test
  public void parseMissingSha() throws Exception {
    assertThat(parser.parse("deadbeef")).isNull();
    assertThat(parser.parse("deadbeefdeadbeefdeadbeefdeadbeefdeadbeef")).isNull();
  }
}
