// 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();
  }
}
