// Copyright (C) 2016 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.gitiles.doc;

import static com.google.common.truth.Truth.assertThat;

import com.google.common.base.CharMatcher;
import com.google.gitiles.GitilesView;
import com.google.gitiles.RootedDocServlet;

import org.eclipse.jgit.lib.Config;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;

@RunWith(JUnit4.class)
public class LinkTest {
  private GitilesView view;
  private Config config;

  @Before
  public void setup() {
    view = GitilesView.revision()
        .setHostName("127.0.0.1")
        .setServletPath("/g")
        .setRepositoryName("repo")
        .setRevision("HEAD")
        .build();
    config = new Config();
  }

  @Test
  public void httpLink() {
    MarkdownToHtml md =
        MarkdownToHtml.builder()
            .setGitilesView(view)
            .setConfig(new MarkdownConfig(config))
            .setFilePath("index.md")
            .build();
    String url;

    url = "http://example.com/foo.html";
    assertThat(md.href(url)).isEqualTo(url);

    url = "https://example.com/foo.html";
    assertThat(md.href(url)).isEqualTo(url);

    url = "//example.com/foo.html";
    assertThat(md.href(url)).isEqualTo(url);
  }

  @Test
  public void gitLink() {
    MarkdownToHtml md =
        MarkdownToHtml.builder()
            .setGitilesView(view)
            .setConfig(new MarkdownConfig(config))
            .setFilePath("index.md")
            .build();
    String url;

    url = "git://example.com/repo.git";
    assertThat(md.href(url)).isEqualTo(url);

    assertThat(md.href("git:example.com/repo.git")).isEqualTo("#zSoyz");
    assertThat(md.href("git://")).isEqualTo("#zSoyz");
    assertThat(md.href("git://example.com/../root")).isEqualTo("#zSoyz");
    assertThat(md.href("git://example.com/root/..")).isEqualTo("#zSoyz");
  }

  @Test
  public void absolutePath() {
    MarkdownToHtml md =
        MarkdownToHtml.builder()
            .setGitilesView(view)
            .setConfig(new MarkdownConfig(config))
            .setFilePath("index.md")
            .build();

    assertThat(md.href("/")).isEqualTo("/g/repo/+/HEAD/");
    assertThat(md.href("/index.md")).isEqualTo("/g/repo/+/HEAD/index.md");
    assertThat(md.href("/doc/index.md")).isEqualTo("/g/repo/+/HEAD/doc/index.md");

    // GitilesView trims trailing '/' from path expressions.
    assertThat(md.href("/doc/")).isEqualTo("/g/repo/+/HEAD/doc");
  }

  @Test
  public void relativePathInRootFile() {
    testMarkdownInRoot(file("/index.md"));
  }

  @Test
  public void relativePathInTreeFile() {
    testMarkdownInTree(file("/doc/index.md"));
  }

  @Test
  public void relativePathInRepositoryIndexReadme() {
    testMarkdownInRoot(repoIndexReadme());
  }

  @Test
  public void relativePathInCommitReadme() {
    testMarkdownInRoot(revisionReadme());
  }

  @Test
  public void relativePathInTreeReadme() {
    testMarkdownInTree(treeReadme("/doc"));
    testMarkdownInTree(treeReadme("/doc/"));
  }

  private static void testMarkdownInRoot(MarkdownToHtml md) {
    assertThat(md.href("#Help")).isEqualTo("#Help");
    assertThat(md.href("setup.md#Help"))
        .isEqualTo("/g/repo/+/HEAD/setup.md#Help");

    assertThat(md.href("setup.md")).isEqualTo("/g/repo/+/HEAD/setup.md");
    assertThat(md.href("./setup.md")).isEqualTo("/g/repo/+/HEAD/setup.md");
    assertThat(md.href("./")).isEqualTo("/g/repo/+/HEAD/");
    assertThat(md.href(".")).isEqualTo("/g/repo/+/HEAD/");

    assertThat(md.href("../")).isEqualTo("#zSoyz");
    assertThat(md.href("../../")).isEqualTo("#zSoyz");
    assertThat(md.href("../..")).isEqualTo("#zSoyz");
    assertThat(md.href("..")).isEqualTo("#zSoyz");
  }

  private static void testMarkdownInTree(MarkdownToHtml md) {
    assertThat(md.href("#Help")).isEqualTo("#Help");
    assertThat(md.href("setup.md#Help"))
        .isEqualTo("/g/repo/+/HEAD/doc/setup.md#Help");

    assertThat(md.href("setup.md")).isEqualTo("/g/repo/+/HEAD/doc/setup.md");
    assertThat(md.href("./setup.md")).isEqualTo("/g/repo/+/HEAD/doc/setup.md");
    assertThat(md.href("../setup.md")).isEqualTo("/g/repo/+/HEAD/setup.md");
    assertThat(md.href("../tech/setup.md")).isEqualTo("/g/repo/+/HEAD/tech/setup.md");

    assertThat(md.href("./")).isEqualTo("/g/repo/+/HEAD/doc");
    assertThat(md.href(".")).isEqualTo("/g/repo/+/HEAD/doc");
    assertThat(md.href("../")).isEqualTo("/g/repo/+/HEAD/");
    assertThat(md.href("..")).isEqualTo("/g/repo/+/HEAD/");

    assertThat(md.href("../../")).isEqualTo("#zSoyz");
    assertThat(md.href("../..")).isEqualTo("#zSoyz");
    assertThat(md.href("../../../")).isEqualTo("#zSoyz");
    assertThat(md.href("../../..")).isEqualTo("#zSoyz");
  }

  private MarkdownToHtml file(String path) {
    return MarkdownToHtml.builder()
        .setGitilesView(GitilesView.doc().copyFrom(view).setPathPart(path).build())
        .setConfig(new MarkdownConfig(config))
        .setFilePath(path)
        .build();
  }

  private MarkdownToHtml repoIndexReadme() {
    return readme(view, "README.md");
  }

  private MarkdownToHtml revisionReadme() {
    return readme(GitilesView.revision().copyFrom(view).build(), "README.md");
  }

  private MarkdownToHtml treeReadme(String path) {
    GitilesView v = GitilesView.path().copyFrom(view).setPathPart(path).build();
    String file = CharMatcher.is('/').trimTrailingFrom(path) + "/README.md";
    return readme(v, file);
  }

  private MarkdownToHtml readme(GitilesView v, String path) {
    return MarkdownToHtml.builder()
        .setGitilesView(v)
        .setConfig(new MarkdownConfig(config))
        .setFilePath(path)
        .build();
  }

  @Test
  public void rootedDocInRoot() {
    testRootedDocInRoot(rootedDoc("/", "/index.md"));
    testRootedDocInRoot(rootedDoc("/index.md", "/index.md"));
  }

  private void testRootedDocInRoot(MarkdownToHtml md) {
    assertThat(md.href("setup.md")).isEqualTo("/setup.md");
    assertThat(md.href("./setup.md")).isEqualTo("/setup.md");
    assertThat(md.href("./")).isEqualTo("/");
    assertThat(md.href(".")).isEqualTo("/");

    assertThat(md.href("../")).isEqualTo("#zSoyz");
    assertThat(md.href("../../")).isEqualTo("#zSoyz");
    assertThat(md.href("../..")).isEqualTo("#zSoyz");
    assertThat(md.href("..")).isEqualTo("#zSoyz");
  }

  @Test
  public void rootedDocInTree() {
    testRootedDocInTree(rootedDoc("/doc", "/doc/index.md"));
    testRootedDocInTree(rootedDoc("/doc/", "/doc/index.md"));
    testRootedDocInTree(rootedDoc("/doc/index.md", "/doc/index.md"));
  }

  private void testRootedDocInTree(MarkdownToHtml md) {
    assertThat(md.href("setup.md")).isEqualTo("/doc/setup.md");
    assertThat(md.href("./setup.md")).isEqualTo("/doc/setup.md");
    assertThat(md.href("../setup.md")).isEqualTo("/setup.md");
    assertThat(md.href("../tech/setup.md")).isEqualTo("/tech/setup.md");

    assertThat(md.href("./")).isEqualTo("/doc");
    assertThat(md.href(".")).isEqualTo("/doc");
    assertThat(md.href("../")).isEqualTo("/");
    assertThat(md.href("..")).isEqualTo("/");

    assertThat(md.href("../../")).isEqualTo("#zSoyz");
    assertThat(md.href("../..")).isEqualTo("#zSoyz");
    assertThat(md.href("../../../")).isEqualTo("#zSoyz");
    assertThat(md.href("../../..")).isEqualTo("#zSoyz");
  }

  private MarkdownToHtml rootedDoc(String path, String file) {
    return MarkdownToHtml.builder()
        .setGitilesView(
            GitilesView.rootedDoc()
                .setHostName("gerritcodereview.com")
                .setServletPath("")
                .setRevision(RootedDocServlet.BRANCH)
                .setPathPart(path)
                .build())
        .setConfig(new MarkdownConfig(config))
        .setFilePath(file)
        .build();
  }

  @Test
  public void automaticRelativePaths() {
    MarkdownToHtml md =
        MarkdownToHtml.builder()
            .setGitilesView(GitilesView.doc().copyFrom(view).setPathPart("docs/index.md").build())
            .setConfig(new MarkdownConfig(config))
            .setFilePath("/docs/index.md")
            .setRequestUri("/g/repo/+/HEAD/docs/index.md")
            .build();

    assertThat(md.href("help.md")).isEqualTo("help.md");
    assertThat(md.href("/docs/help.md")).isEqualTo("help.md");
    assertThat(md.href("technical/format.md")).isEqualTo("technical/format.md");
    assertThat(md.href("/docs/technical/format.md")).isEqualTo("technical/format.md");

    assertThat(md.href("../README.md")).isEqualTo("/g/repo/+/HEAD/README.md");
    assertThat(md.href("../src/catalog.md")).isEqualTo("/g/repo/+/HEAD/src/catalog.md");
    assertThat(md.href("/src/catalog.md")).isEqualTo("/g/repo/+/HEAD/src/catalog.md");
  }
}
