// 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 == Revision.NULL, "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 != Revision.NULL, "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 != Revision.NULL, "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 (oldRevision == Revision.NULL) {
      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 != Revision.NULL) {
          url.append('/');
          if (oldRevision != Revision.NULL) {
            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 != Revision.NULL) {
        // TODO(dborowitz): Add something in the navigation area (probably not
        // a breadcrumb) to allow switching between /+log/ and /+/.
        if (oldRevision == Revision.NULL) {
          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 != Revision.NULL) {
      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 rev2 == Revision.NULL
        || 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);
    }
  }
}
