// 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.base.MoreObjects.firstNonNull;
import static com.google.common.base.MoreObjects.toStringHelper;
import static com.google.common.base.Preconditions.checkArgument;
import static com.google.common.base.Preconditions.checkNotNull;
import static com.google.common.base.Preconditions.checkState;
import static com.google.gitiles.GitilesUrls.escapeName;
import static java.nio.charset.StandardCharsets.UTF_8;

import com.google.common.annotations.VisibleForTesting;
import com.google.common.base.Joiner;
import com.google.common.base.MoreObjects.ToStringHelper;
import com.google.common.base.Splitter;
import com.google.common.base.Strings;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.LinkedListMultimap;
import com.google.common.collect.ListMultimap;
import com.google.common.collect.Multimaps;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.EnumSet;
import java.util.List;
import java.util.Map;
import javax.servlet.http.HttpServletRequest;
import org.eclipse.jgit.lib.Constants;
import org.eclipse.jgit.revwalk.RevObject;

/**
 * Information about a view in Gitiles.
 *
 * <p>Views are uniquely identified by a type, and dispatched to servlet types by {@link
 * GitilesServlet}. This class contains the list of all types, as well as some methods containing
 * basic information parsed from the URL. Construction happens in {@link ViewFilter}.
 */
public class GitilesView {
  private static final String DEFAULT_ARCHIVE_EXTENSION = ".tar.gz";

  /** All the possible view types supported in the application. */
  public enum Type {
    HOST_INDEX,
    REPOSITORY_INDEX,
    REFS,
    REVISION,
    PATH,
    SHOW,
    DIFF,
    LOG,
    DESCRIBE,
    ARCHIVE,
    BLAME,
    DOC,
    ROOTED_DOC;
  }

  /** Exception thrown when building a view that is invalid. */
  public static class InvalidViewException extends IllegalStateException {
    private static final long serialVersionUID = 1L;

    public InvalidViewException(String msg) {
      super(msg);
    }
  }

  /** Builder for views. */
  public static class Builder {
    private Type type;
    private final ListMultimap<String, String> params = LinkedListMultimap.create();

    private String hostName;
    private String servletPath;
    private String repositoryPrefix;
    private String repositoryName;
    private Revision revision = Revision.NULL;
    private Revision oldRevision = Revision.NULL;
    private String path;
    private String extension;
    private String anchor;

    private Builder(Type type) {
      this.type = type;
    }

    public Builder copyFrom(GitilesView other) {
      if (type == Type.DOC && other.type == Type.ROOTED_DOC) {
        type = Type.ROOTED_DOC;
      }

      hostName = other.hostName;
      servletPath = other.servletPath;
      switch (type) {
        case HOST_INDEX:
          repositoryPrefix = other.repositoryPrefix;
          break;
        case LOG:
        case DIFF:
          oldRevision = other.oldRevision;
          // $FALL-THROUGH$
        case PATH:
        case DOC:
        case ROOTED_DOC:
        case ARCHIVE:
        case BLAME:
        case SHOW:
          path = other.path;
          // $FALL-THROUGH$
        case REVISION:
          revision = other.revision;
          // $FALL-THROUGH$
        case DESCRIBE:
        case REFS:
        case REPOSITORY_INDEX:
          repositoryName = other.repositoryName;
          // $FALL-THROUGH$
        default:
          break;
      }
      if (other.type == type) {
        // Only copy params for matching type.
        params.putAll(other.params);
        if (type == Type.ARCHIVE) {
          extension = other.extension;
        }
      }
      return this;
    }

    public Builder copyFrom(HttpServletRequest req) {
      return copyFrom(ViewFilter.getView(req));
    }

    public Builder setHostName(String hostName) {
      this.hostName = checkNotNull(hostName);
      return this;
    }

    public String getHostName() {
      return hostName;
    }

    public Builder setServletPath(String servletPath) {
      this.servletPath = checkNotNull(servletPath);
      return this;
    }

    public String getServletPath() {
      return servletPath;
    }

    public Builder setRepositoryPrefix(String prefix) {
      if (type == Type.HOST_INDEX) {
        this.repositoryPrefix =
            prefix != null ? Strings.emptyToNull(maybeTrimLeadingAndTrailingSlash(prefix)) : null;
        return this;
      }
      throw new IllegalStateException(
          String.format("cannot set repository prefix on %s view", type));
    }

    public Builder setRepositoryName(String repositoryName) {
      if (type == Type.HOST_INDEX) {
        throw new IllegalStateException(
            String.format("cannot set repository name on %s view", type));
      }
      this.repositoryName = checkNotNull(repositoryName);
      return this;
    }

    public String getRepositoryName() {
      return repositoryName;
    }

    public Builder setRevision(Revision revision) {
      switch (type) {
        case HOST_INDEX:
        case REPOSITORY_INDEX:
        case REFS:
        case DESCRIBE:
          throw new IllegalStateException(String.format("cannot set revision on %s view", type));
        case ARCHIVE:
        case BLAME:
        case DIFF:
        case DOC:
        case LOG:
        case PATH:
        case REVISION:
        case ROOTED_DOC:
        case SHOW:
        default:
          this.revision = checkNotNull(revision);
          return this;
      }
    }

    public Builder setRevision(String name) {
      return setRevision(Revision.named(name));
    }

    public Builder setRevision(RevObject obj) {
      return setRevision(Revision.peeled(obj.name(), obj));
    }

    public Builder setRevision(String name, RevObject obj) {
      return setRevision(Revision.peeled(name, obj));
    }

    public Revision getRevision() {
      return revision;
    }

    public Builder setOldRevision(Revision revision) {
      if (type != Type.DIFF && type != Type.LOG) {
        revision = firstNonNull(revision, Revision.NULL);
        checkState(Revision.isNull(revision), "cannot set old revision on %s view", type);
      }
      this.oldRevision = revision;
      return this;
    }

    public Builder setOldRevision(RevObject obj) {
      return setOldRevision(Revision.peeled(obj.name(), obj));
    }

    public Builder setOldRevision(String name, RevObject obj) {
      return setOldRevision(Revision.peeled(name, obj));
    }

    public Revision getOldRevision() {
      return oldRevision;
    }

    public Builder setPathPart(String path) {
      switch (type) {
        case PATH:
        case DIFF:
        case SHOW:
          checkState(path != null, "cannot set null path on %s view", type);
          break;
        case BLAME:
        case ARCHIVE:
        case DESCRIBE:
        case REFS:
        case LOG:
        case DOC:
        case ROOTED_DOC:
          break;
        case HOST_INDEX:
        case REPOSITORY_INDEX:
        case REVISION:
        default:
          checkState(path == null, "cannot set path on %s view", type);
          break;
      }
      this.path = path != null ? maybeTrimLeadingAndTrailingSlash(path) : null;
      return this;
    }

    public String getPathPart() {
      return path;
    }

    public Builder setExtension(String extension) {
      if (type != Type.ARCHIVE) {
        checkState(extension == null, "cannot set extension on %s view", type);
      }
      this.extension = extension;
      return this;
    }

    public String getExtension() {
      return extension;
    }

    public Builder putParam(String key, String value) {
      params.put(key, value);
      return this;
    }

    public Builder replaceParam(String key, String value) {
      params.replaceValues(key, ImmutableList.of(value));
      return this;
    }

    public Builder putAllParams(Map<String, String[]> params) {
      for (Map.Entry<String, String[]> e : params.entrySet()) {
        this.params.putAll(e.getKey(), Arrays.asList(e.getValue()));
      }
      return this;
    }

    public ListMultimap<String, String> getParams() {
      return params;
    }

    public Builder setAnchor(String anchor) {
      this.anchor = anchor;
      return this;
    }

    public String getAnchor() {
      return anchor;
    }

    public GitilesView build() {
      switch (type) {
        case HOST_INDEX:
          checkHostIndex();
          break;
        case REPOSITORY_INDEX:
          checkRepositoryIndex();
          break;
        case REFS:
          checkRefs();
          break;
        case DESCRIBE:
          checkDescribe();
          break;
        case REVISION:
          checkRevision();
          break;
        case PATH:
        case SHOW:
        case DOC:
          checkPath();
          break;
        case DIFF:
          checkDiff();
          break;
        case LOG:
          checkLog();
          break;
        case ARCHIVE:
          checkArchive();
          break;
        case BLAME:
          checkBlame();
          break;
        case ROOTED_DOC:
          checkRootedDoc();
          break;
      }
      return new GitilesView(
          type,
          hostName,
          servletPath,
          repositoryPrefix,
          repositoryName,
          revision,
          oldRevision,
          path,
          extension,
          params,
          anchor);
    }

    public String toUrl() {
      return build().toUrl();
    }

    private void checkView(boolean expr, String msg, Object... args) {
      if (!expr) {
        throw new InvalidViewException(String.format(msg, args));
      }
    }

    private void checkHostIndex() {
      checkView(hostName != null, "missing hostName on %s view", type);
      checkView(servletPath != null, "missing servletPath on %s view", type);
    }

    private void checkRepositoryIndex() {
      checkView(repositoryName != null, "missing repository name on %s view", type);
      checkHostIndex();
    }

    private void checkRefs() {
      checkRepositoryIndex();
    }

    private void checkDescribe() {
      checkRepositoryIndex();
    }

    private void checkRevision() {
      checkView(!Revision.isNull(revision), "missing revision on %s view", type);
      checkRepositoryIndex();
    }

    private void checkDiff() {
      checkPath();
    }

    private void checkLog() {
      checkRepositoryIndex();
    }

    private void checkPath() {
      checkView(path != null, "missing path on %s view", type);
      checkRevision();
    }

    private void checkArchive() {
      checkRevision();
    }

    private void checkBlame() {
      checkPath();
    }

    private void checkRootedDoc() {
      checkView(hostName != null, "missing hostName on %s view", type);
      checkView(servletPath != null, "missing hostName on %s view", type);
      checkView(!Revision.isNull(revision), "missing revision on %s view", type);
      checkView(path != null, "missing path on %s view", type);
    }
  }

  public static Builder hostIndex() {
    return new Builder(Type.HOST_INDEX);
  }

  public static Builder repositoryIndex() {
    return new Builder(Type.REPOSITORY_INDEX);
  }

  public static Builder refs() {
    return new Builder(Type.REFS);
  }

  public static Builder describe() {
    return new Builder(Type.DESCRIBE);
  }

  public static Builder revision() {
    return new Builder(Type.REVISION);
  }

  public static Builder path() {
    return new Builder(Type.PATH);
  }

  public static Builder show() {
    return new Builder(Type.SHOW);
  }

  public static Builder diff() {
    return new Builder(Type.DIFF);
  }

  public static Builder log() {
    return new Builder(Type.LOG);
  }

  public static Builder archive() {
    return new Builder(Type.ARCHIVE);
  }

  public static Builder blame() {
    return new Builder(Type.BLAME);
  }

  public static Builder doc() {
    return new Builder(Type.DOC);
  }

  public static Builder rootedDoc() {
    return new Builder(Type.ROOTED_DOC);
  }

  static String maybeTrimLeadingAndTrailingSlash(String str) {
    if (str.startsWith("/")) {
      str = str.substring(1);
    }
    return !str.isEmpty() && str.endsWith("/") ? str.substring(0, str.length() - 1) : str;
  }

  private final Type type;
  private final String hostName;
  private final String servletPath;
  private final String repositoryPrefix;
  private final String repositoryName;
  private final Revision revision;
  private final Revision oldRevision;
  private final String path;
  private final String extension;
  private final ListMultimap<String, String> params;
  private final String anchor;

  private GitilesView(
      Type type,
      String hostName,
      String servletPath,
      String repositoryPrefix,
      String repositoryName,
      Revision revision,
      Revision oldRevision,
      String path,
      String extension,
      ListMultimap<String, String> params,
      String anchor) {
    this.type = type;
    this.hostName = hostName;
    this.servletPath = servletPath;
    this.repositoryPrefix = repositoryPrefix;
    this.repositoryName = repositoryName;
    this.revision = firstNonNull(revision, Revision.NULL);
    this.oldRevision = firstNonNull(oldRevision, Revision.NULL);
    this.path = path;
    this.extension = extension;
    this.params = Multimaps.unmodifiableListMultimap(params);
    this.anchor = anchor;
  }

  public Builder copyFrom(GitilesView other) {
    return new Builder(other.type).copyFrom(this);
  }

  public Builder toBuilder() {
    return copyFrom(this);
  }

  public String getHostName() {
    return hostName;
  }

  public String getServletPath() {
    return servletPath;
  }

  public String getRepositoryPrefix() {
    return repositoryPrefix;
  }

  public String getRepositoryName() {
    return repositoryName;
  }

  public Revision getRevision() {
    return revision;
  }

  public Revision getOldRevision() {
    return oldRevision;
  }

  public String getRevisionRange() {
    if (Revision.isNull(oldRevision)) {
      if (type == Type.LOG || type == Type.DIFF) {
        // For types that require two revisions, NULL indicates the empty
        // tree/commit.
        return revision.getName() + "^!";
      }
      // For everything else NULL indicates it is not a range, just a single
      // revision.
      return null;
    } else if (type == Type.DIFF && isFirstParent(revision, oldRevision)) {
      return revision.getName() + "^!";
    } else {
      return oldRevision.getName() + ".." + revision.getName();
    }
  }

  public String getPathPart() {
    return path;
  }

  public String getExtension() {
    return extension;
  }

  public ListMultimap<String, String> getParameters() {
    return params;
  }

  public String getAnchor() {
    return anchor;
  }

  public Type getType() {
    return type;
  }

  @Override
  public String toString() {
    ToStringHelper b =
        toStringHelper(type.toString())
            .omitNullValues()
            .add("host", hostName)
            .add("servlet", servletPath)
            .add("prefix", repositoryPrefix)
            .add("repo", repositoryName)
            .add("rev", revision)
            .add("old", oldRevision)
            .add("path", path)
            .add("extension", extension);
    if (!params.isEmpty()) {
      b.add("params", params);
    }
    b.add("anchor", anchor);
    return b.toString();
  }

  /** @return an escaped, relative URL representing this view. */
  public String toUrl() {
    StringBuilder url = new StringBuilder(servletPath).append('/');
    ListMultimap<String, String> params = this.params;
    switch (type) {
      case HOST_INDEX:
        if (repositoryPrefix != null) {
          url.append(repositoryPrefix).append('/');
        }
        params = LinkedListMultimap.create();
        if (repositoryPrefix == null && !this.params.containsKey("format")) {
          params.put("format", FormatType.HTML.toString());
        }
        params.putAll(this.params);
        break;
      case REPOSITORY_INDEX:
        url.append(repositoryName).append('/');
        break;
      case REFS:
        url.append(repositoryName).append("/+refs");
        break;
      case DESCRIBE:
        url.append(repositoryName).append("/+describe");
        break;
      case REVISION:
        url.append(repositoryName).append("/+/").append(revision.getName());
        break;
      case ARCHIVE:
        url.append(repositoryName).append("/+archive/").append(revision.getName());
        if (path != null) {
          url.append('/').append(path);
        }
        url.append(firstNonNull(extension, DEFAULT_ARCHIVE_EXTENSION));
        break;
      case PATH:
        url.append(repositoryName)
            .append("/+/")
            .append(revision.getName())
            .append('/')
            .append(path);
        break;
      case SHOW:
        url.append(repositoryName)
            .append("/+show/")
            .append(revision.getName())
            .append('/')
            .append(path);
        break;
      case DIFF:
        url.append(repositoryName).append("/+/");
        if (isFirstParent(revision, oldRevision)) {
          url.append(revision.getName()).append("^!");
        } else {
          url.append(oldRevision.getName()).append("..").append(revision.getName());
        }
        url.append('/').append(path);
        break;
      case LOG:
        url.append(repositoryName).append("/+log");
        if (!Revision.isNull(revision)) {
          url.append('/');
          if (!Revision.isNull(oldRevision)) {
            url.append(oldRevision.getName()).append("..");
          }
          url.append(revision.getName());
          if (path != null) {
            url.append('/').append(path);
          }
        }
        break;
      case BLAME:
        url.append(repositoryName)
            .append("/+blame/")
            .append(revision.getName())
            .append('/')
            .append(path);
        break;
      case DOC:
        url.append(repositoryName);
        if (path != null && path.endsWith(".md")) {
          url.append("/+/");
        } else {
          url.append("/+doc/");
        }
        url.append(revision.getName());
        if (path != null) {
          url.append('/').append(path);
        }
        break;
      case ROOTED_DOC:
        if (path != null) {
          url.append(path);
        }
        break;
      default:
        throw new IllegalStateException("Unknown view type: " + type);
    }
    String baseUrl = escapeName(url.toString());
    url = new StringBuilder();
    if (!params.isEmpty()) {
      url.append('?').append(paramsToString(params));
    }
    if (!Strings.isNullOrEmpty(anchor)) {
      url.append('#').append(escapeName(anchor));
    }
    return baseUrl + url;
  }

  /**
   * @return a list of maps with "text" and "url" keys for all file paths leading up to the path
   *     represented by this view. All URLs allow auto-diving into one-entry subtrees; see also
   *     {@link #getBreadcrumbs(List)}.
   */
  public List<Map<String, String>> getBreadcrumbs() {
    return getBreadcrumbs(null);
  }

  private static final EnumSet<Type> NON_HTML_TYPES = EnumSet.of(Type.DESCRIBE, Type.ARCHIVE);

  /**
   * @param hasSingleTree list of booleans, one per path entry in this view's path excluding the
   *     leaf. True entries indicate the tree at that path only has a single entry that is another
   *     tree.
   * @return a list of maps with "text" and "url" keys for all file paths leading up to the path
   *     represented by this view. URLs whose corresponding entry in {@code hasSingleTree} is true
   *     will disable auto-diving into one-entry subtrees.
   */
  public List<Map<String, String>> getBreadcrumbs(List<Boolean> hasSingleTree) {
    checkArgument(!NON_HTML_TYPES.contains(type), "breadcrumbs for %s view not supported", type);
    checkArgument(
        type != Type.REFS || Strings.isNullOrEmpty(path),
        "breadcrumbs for REFS view with path not supported");
    checkArgument(
        hasSingleTree == null || type == Type.PATH, "hasSingleTree must be null for %s view", type);
    String path = this.path;
    ImmutableList.Builder<Map<String, String>> breadcrumbs = ImmutableList.builder();
    breadcrumbs.add(breadcrumb(hostName, hostIndex().copyFrom(this).setRepositoryPrefix(null)));
    if (repositoryPrefix != null) {
      breadcrumbs.addAll(hostIndexBreadcrumbs(repositoryPrefix));
    } else if (repositoryName != null) {
      breadcrumbs.addAll(hostIndexBreadcrumbs(repositoryName));
    }
    if (type == Type.DIFF) {
      // TODO(dborowitz): Tweak the breadcrumbs template to allow us to render
      // separate links in "old..new".
      breadcrumbs.add(breadcrumb(getRevisionRange(), diff().copyFrom(this).setPathPart("")));
    } else if (type == Type.LOG) {
      if (!Revision.isNull(revision)) {
        // TODO(dborowitz): Add something in the navigation area (probably not
        // a breadcrumb) to allow switching between /+log/ and /+/.
        if (Revision.isNull(oldRevision)) {
          breadcrumbs.add(breadcrumb(revision.getName(), log().copyFrom(this).setPathPart(null)));
        } else {
          breadcrumbs.add(breadcrumb(getRevisionRange(), log().copyFrom(this).setPathPart(null)));
        }
      } else {
        breadcrumbs.add(breadcrumb(Constants.HEAD, log().copyFrom(this)));
      }
      path = Strings.emptyToNull(path);
    } else if (!Revision.isNull(revision)) {
      breadcrumbs.add(breadcrumb(revision.getName(), revision().copyFrom(this)));
    }
    if (path != null) {
      if (type != Type.LOG && type != Type.REFS) {
        // The "." breadcrumb would be no different for LOG or REFS.
        breadcrumbs.add(breadcrumb(".", copyWithPath(false).setPathPart("")));
      }
      StringBuilder cur = new StringBuilder();
      List<String> parts = PathUtil.SPLITTER.omitEmptyStrings().splitToList(path);
      checkArgument(
          hasSingleTree == null
              || (parts.isEmpty() && hasSingleTree.isEmpty())
              || hasSingleTree.size() == parts.size() - 1,
          "hasSingleTree has wrong number of entries");
      for (int i = 0; i < parts.size(); i++) {
        String part = parts.get(i);
        cur.append(part).append('/');
        String curPath = cur.toString();
        boolean isLeaf = i == parts.size() - 1;
        Builder builder = copyWithPath(isLeaf).setPathPart(curPath);
        if (hasSingleTree != null && i < parts.size() - 1 && hasSingleTree.get(i)) {
          builder.replaceParam(PathServlet.AUTODIVE_PARAM, PathServlet.NO_AUTODIVE_VALUE);
        }
        breadcrumbs.add(breadcrumb(part, builder));
      }
    }
    return breadcrumbs.build();
  }

  private List<Map<String, String>> hostIndexBreadcrumbs(String name) {
    List<String> parts = Splitter.on('/').splitToList(name);
    List<Map<String, String>> r = new ArrayList<>(parts.size());
    for (int i = 0; i < parts.size(); i++) {
      String prefix = Joiner.on('/').join(parts.subList(0, i + 1));
      r.add(breadcrumb(parts.get(i), hostIndex().copyFrom(this).setRepositoryPrefix(prefix)));
    }
    return r;
  }

  private static Map<String, String> breadcrumb(String text, Builder url) {
    return ImmutableMap.of("text", text, "url", url.toUrl());
  }

  private Builder copyWithPath(boolean isLeaf) {
    Builder copy;
    switch (type) {
      case DIFF:
        copy = diff();
        break;
      case LOG:
        copy = log();
        break;
      case BLAME:
        copy = isLeaf ? blame() : path();
        break;
      case ARCHIVE:
      case DESCRIBE:
      case DOC:
      case HOST_INDEX:
      case PATH:
      case REFS:
      case REPOSITORY_INDEX:
      case REVISION:
      case ROOTED_DOC:
      case SHOW:
      default:
        copy = path();
        break;
    }
    return copy.copyFrom(this);
  }

  private static boolean isFirstParent(Revision rev1, Revision rev2) {
    return Revision.isNull(rev2)
        || rev2.getName().equals(rev1.getName() + "^")
        || rev2.getName().equals(rev1.getName() + "~1");
  }

  @VisibleForTesting
  static String paramsToString(ListMultimap<String, String> params) {
    try {
      StringBuilder sb = new StringBuilder();
      boolean first = true;
      for (Map.Entry<String, String> e : params.entries()) {
        if (!first) {
          sb.append('&');
        } else {
          first = false;
        }
        sb.append(URLEncoder.encode(e.getKey(), UTF_8.name()));
        if (!"".equals(e.getValue())) {
          sb.append('=').append(URLEncoder.encode(e.getValue(), UTF_8.name()));
        }
      }
      return sb.toString();
    } catch (UnsupportedEncodingException e) {
      throw new IllegalStateException(e);
    }
  }
}
