// 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 com.google.gitiles.TestGitilesUrls.URLS;

import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import com.google.gitiles.RefServlet.RefJsonData;
import com.google.gson.reflect.TypeToken;

import org.eclipse.jgit.lib.ObjectId;
import org.eclipse.jgit.lib.Repository;
import org.eclipse.jgit.revwalk.RevCommit;
import org.eclipse.jgit.revwalk.RevTag;
import org.eclipse.jgit.revwalk.RevWalk;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;

import java.io.IOException;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;

/** Tests for {@link RefServlet}. */
@RunWith(JUnit4.class)
public class RefServletTest extends ServletTest {
  private void setUpSimpleRefs() throws Exception {
    RevCommit commit = repo.branch("refs/heads/master").commit().create();
    repo.update("refs/heads/branch", commit);
    repo.update("refs/tags/ctag", commit);
    RevTag tag = repo.tag("atag", commit);
    repo.update("refs/tags/atag", tag);
    repo.getRepository().updateRef("HEAD").link("refs/heads/master");
  }

  @Test
  public void evilRefName() throws Exception {
    setUpSimpleRefs();
    String evilRefName = "refs/evil/<script>window.close();</script>/&foo";
    assertThat(Repository.isValidRefName(evilRefName)).isTrue();
    repo.branch(evilRefName).commit().create();

    FakeHttpServletResponse res = buildText("/repo/+refs/evil");
    assertThat(res.getActualBodyString()).isEqualTo(
        id(evilRefName) + " refs/evil/&lt;script&gt;window.close();&lt;/script&gt;/&amp;foo\n");
  }

  @Test
  public void getRefsTextAll() throws Exception {
    setUpSimpleRefs();
    FakeHttpServletResponse res = buildText("/repo/+refs");

    assertThat(res.getActualBodyString()).isEqualTo(
        id("HEAD") + " HEAD\n"
        + id("refs/heads/branch") + " refs/heads/branch\n"
        + id("refs/heads/master") + " refs/heads/master\n"
        + id("refs/tags/atag") + " refs/tags/atag\n"
        + peeled("refs/tags/atag") + " refs/tags/atag^{}\n"
        + id("refs/tags/ctag") + " refs/tags/ctag\n");
  }

  @Test
  public void getRefsTextAllTrailingSlash() throws Exception {
    setUpSimpleRefs();
    FakeHttpServletResponse res = buildText("/repo/+refs/");

    assertThat(res.getActualBodyString()).isEqualTo(
        id("HEAD") + " HEAD\n"
        + id("refs/heads/branch") + " refs/heads/branch\n"
        + id("refs/heads/master") + " refs/heads/master\n"
        + id("refs/tags/atag") + " refs/tags/atag\n"
        + peeled("refs/tags/atag") + " refs/tags/atag^{}\n"
        + id("refs/tags/ctag") + " refs/tags/ctag\n");
  }

  @Test
  public void getRefsHeadsText() throws Exception {
    setUpSimpleRefs();
    FakeHttpServletResponse res = buildText("/repo/+refs/heads");

    assertThat(res.getActualBodyString()).isEqualTo(
        id("refs/heads/branch") + " refs/heads/branch\n"
        + id("refs/heads/master") + " refs/heads/master\n");
  }

  @Test
  public void getRefsHeadsTextTrailingSlash() throws Exception {
    setUpSimpleRefs();
    FakeHttpServletResponse res = buildText("/repo/+refs/heads/");

    assertThat(res.getActualBodyString()).isEqualTo(
        id("refs/heads/branch") + " refs/heads/branch\n"
        + id("refs/heads/master") + " refs/heads/master\n");
  }

  @Test
  public void noHeadText() throws Exception {
    setUpSimpleRefs();
    FakeHttpServletResponse res = buildText("/repo/+refs/HEAD");

    // /+refs/foo means refs/foo(/*), so this is empty.
    assertThat(res.getActualBodyString()).isEqualTo("");
  }

  @Test
  public void singleHeadText() throws Exception {
    setUpSimpleRefs();
    FakeHttpServletResponse res = buildText("/repo/+refs/heads/master");

    assertThat(res.getActualBodyString()).isEqualTo(
        id("refs/heads/master") + " refs/heads/master\n");
  }

  @Test
  public void singlePeeledTagText() throws Exception {
    setUpSimpleRefs();
    FakeHttpServletResponse res = buildText("/repo/+refs/tags/atag");

    assertThat(res.getActualBodyString()).isEqualTo(
        id("refs/tags/atag") + " refs/tags/atag\n"
        + peeled("refs/tags/atag") + " refs/tags/atag^{}\n");
  }

  @Test
  public void getRefsJsonAll() throws Exception {
    setUpSimpleRefs();
    Map<String, RefJsonData> result = buildRefJson("/repo/+refs");
    List<String> keys = ImmutableList.copyOf(result.keySet());
    assertThat(keys)
        .containsExactly(
            "HEAD",
            "refs/heads/branch",
            "refs/heads/master",
            "refs/tags/atag",
            "refs/tags/ctag")
        .inOrder();

    RefJsonData head = result.get(keys.get(0));
    assertThat(head.value).isEqualTo(id("HEAD"));
    assertThat(head.peeled).isNull();
    assertThat(head.target).isEqualTo("refs/heads/master");

    RefJsonData branch = result.get(keys.get(1));
    assertThat(branch.value).isEqualTo(id("refs/heads/branch"));
    assertThat(branch.peeled).isNull();
    assertThat(branch.target).isNull();

    RefJsonData master = result.get(keys.get(2));
    assertThat(master.value).isEqualTo(id("refs/heads/master"));
    assertThat(master.peeled).isNull();
    assertThat(master.target).isNull();

    RefJsonData atag = result.get(keys.get(3));
    assertThat(atag.value).isEqualTo(id("refs/tags/atag"));
    assertThat(atag.peeled).isEqualTo(peeled("refs/tags/atag"));
    assertThat(atag.target).isNull();

    RefJsonData ctag = result.get(keys.get(4));
    assertThat(ctag.value).isEqualTo(id("refs/tags/ctag"));
    assertThat(ctag.peeled).isNull();
    assertThat(ctag.target).isNull();
  }

  @Test
  public void getRefsHeadsJson() throws Exception {
    setUpSimpleRefs();
    Map<String, RefJsonData> result = buildRefJson("/repo/+refs/heads");
    List<String> keys = ImmutableList.copyOf(result.keySet());
    assertThat(keys)
        .containsExactly(
            "branch",
            "master")
        .inOrder();

    RefJsonData branch = result.get(keys.get(0));
    assertThat(branch.value).isEqualTo(id("refs/heads/branch"));
    assertThat(branch.peeled).isNull();
    assertThat(branch.target).isNull();

    RefJsonData master = result.get(keys.get(1));
    assertThat(master.value).isEqualTo(id("refs/heads/master"));
    assertThat(master.peeled).isNull();
    assertThat(master.target).isNull();
  }

  private Map<String, RefJsonData> buildRefJson(String path) throws Exception {
    return buildJson(new TypeToken<Map<String, RefJsonData>>() {}, path);
  }

  @Test
  public void emptySoy() throws Exception {
    assertThat(buildBranchesSoyData()).isEmpty();
    assertThat(buildTagsSoyData()).isEmpty();
  }

  @Test
  public void branchesAndTagsSoy() throws Exception {
    repo.branch("refs/heads/foo").commit().create();
    repo.branch("refs/heads/bar").commit().create();
    repo.branch("refs/tags/baz").commit().create();
    repo.branch("refs/nope/quux").commit().create();

    assertThat(buildBranchesSoyData())
        .containsExactly(
            ref("/b/test/+/bar", "bar"),
            ref("/b/test/+/foo", "foo"))
        .inOrder();
    assertThat(buildTagsSoyData())
        .containsExactly(
            ref("/b/test/+/baz", "baz"))
        .inOrder();
  }

  @Test
  public void ambiguousBranchSoy() throws Exception {
    repo.branch("refs/heads/foo").commit().create();
    repo.branch("refs/heads/bar").commit().create();
    repo.branch("refs/tags/foo").commit().create();

    assertThat(buildBranchesSoyData())
        .containsExactly(
            ref("/b/test/+/bar", "bar"),
            ref("/b/test/+/refs/heads/foo", "foo"))
        .inOrder();
    assertThat(buildTagsSoyData())
        .containsExactly(
            // refs/tags/ is searched before refs/heads/, so this does not
            // appear ambiguous.
            ref("/b/test/+/foo", "foo"))
        .inOrder();
  }

  @Test
  public void ambiguousRelativeToNonBranchOrTagSoy() throws Exception {
    repo.branch("refs/foo").commit().create();
    repo.branch("refs/heads/foo").commit().create();
    repo.branch("refs/tags/foo").commit().create();

    assertThat(buildBranchesSoyData())
        .containsExactly(
            ref("/b/test/+/refs/heads/foo", "foo"))
        .inOrder();
    assertThat(buildTagsSoyData())
        .containsExactly(
            ref("/b/test/+/refs/tags/foo", "foo"))
        .inOrder();
  }

  @Test
  public void refsHeadsSoy() throws Exception {
    repo.branch("refs/heads/foo").commit().create();
    repo.branch("refs/heads/refs/heads/foo").commit().create();

    assertThat(buildBranchesSoyData())
        .containsExactly(
            ref("/b/test/+/foo", "foo"),
            ref("/b/test/+/refs/heads/refs/heads/foo", "refs/heads/foo"))
        .inOrder();
  }

  private HttpServletRequest buildSoyRequest() {
    HttpServletRequest req = FakeHttpServletRequest.newRequest(repo.getRepository());
    ViewFilter.setView(req, GitilesView.repositoryIndex()
        .setHostName(URLS.getHostName(req))
        .setServletPath(req.getServletPath())
        .setRepositoryName("test")
        .build());
    return req;
  }

  private List<?> buildBranchesSoyData() throws Exception {
    return RefServlet.getBranchesSoyData(buildSoyRequest(), Integer.MAX_VALUE);
  }

  private List<?> buildTagsSoyData() throws Exception {
    try (RevWalk rw = new RevWalk(repo.getRepository())) {
      return RefServlet.getTagsSoyData(buildSoyRequest(),
          new TimeCache(TimeCache.defaultBuilder()), rw, Integer.MAX_VALUE);
    }
  }

  private String id(String refName) throws IOException {
    return ObjectId.toString(repo.getRepository().getRef(refName).getObjectId());
  }

  private String peeled(String refName) throws IOException {
    return ObjectId.toString(repo.getRepository().peel(
          repo.getRepository().getRef(refName)).getPeeledObjectId());
  }

  private Map<String, String> ref(String url, String name) {
    return ImmutableMap.of("url", url, "name", name);
  }
}
