// Copyright 2015 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.doc;

import static java.util.stream.Collectors.toSet;

import com.google.common.base.CharMatcher;
import com.google.common.base.Splitter;
import com.google.gitiles.doc.html.HtmlBuilder;
import com.google.template.soy.shared.internal.Sanitizers;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import javax.annotation.Nullable;
import org.commonmark.node.Heading;
import org.commonmark.node.Node;
import org.eclipse.jgit.util.RawParseUtils;

class Navbar {
  private static final Pattern META_LINK =
      Pattern.compile(
          "^\\[(logo|home|extensions)\\]:\\s*(.+)$", Pattern.MULTILINE | Pattern.CASE_INSENSITIVE);
  private static final Pattern EXTENSIONS_LINK =
      Pattern.compile("^\\[extensions\\]:\\s*(.+)$", Pattern.MULTILINE | Pattern.CASE_INSENSITIVE);

  private MarkdownConfig cfg;
  private MarkdownToHtml fmt;
  private Node node;
  private String siteTitle;
  private String logoUrl;
  private String homeUrl;

  Navbar() {}

  MarkdownConfig getConfig() {
    return cfg;
  }

  Navbar setConfig(MarkdownConfig cfg) {
    this.cfg = cfg;
    return this;
  }

  Navbar setFormatter(MarkdownToHtml html) {
    this.fmt = html;
    return this;
  }

  Navbar setMarkdown(byte[] md) {
    if (md != null && md.length > 0) {
      parse(RawParseUtils.decode(md));
    }
    return this;
  }

  Map<String, Object> toSoyData() {
    Map<String, Object> data = new HashMap<>();
    data.put("siteTitle", siteTitle);
    data.put("logoUrl", logo());
    data.put("homeUrl", homeUrl != null ? fmt.href(homeUrl) : null);
    data.put("navbarHtml", node != null ? fmt.toSoyHtml(node) : null);
    return data;
  }

  private @Nullable Object logo() {
    if (logoUrl == null) {
      return null;
    }

    String url = fmt.image(logoUrl);
    if (HtmlBuilder.isValidHttpUri(url)) {
      return url;
    } else if (HtmlBuilder.isImageDataUri(url)) {
      return Sanitizers.filterImageDataUri(url);
    } else {
      return SoyConstants.IMAGE_URI_INNOCUOUS_OUTPUT;
    }
  }

  private void parse(String markdown) {
    String md = extractMetadata(markdown);
    node = GitilesMarkdown.parse(cfg, md);
    extractSiteTitle();
  }

  private void extractSiteTitle() {
    for (Node c = node.getFirstChild(); c != null; c = c.getNext()) {
      if (c instanceof Heading) {
        Heading h = (Heading) c;
        if (h.getLevel() == 1) {
          siteTitle = MarkdownUtil.getInnerText(h);
          h.unlink();
          break;
        }
      }
    }
  }

  private String extractMetadata(String markdown) {
    boolean extensionsFound = false;
    Matcher m = META_LINK.matcher(markdown);
    while (m.find()) {
      String key = m.group(1).toLowerCase();
      String url = m.group(2).trim();
      switch (key) {
        case "logo":
          logoUrl = url;
          break;
        case "home":
          homeUrl = url;
          break;
        case "extensions":
          extensionsFound = true;
          Set<String> names = splitExtensionNames(url);
          cfg = cfg.copyWithExtensions(enabled(names), disabled(names));
          break;
      }
    }
    if (extensionsFound) {
      return EXTENSIONS_LINK.matcher(markdown).replaceAll("");
    }
    return markdown;
  }

  private static Set<String> splitExtensionNames(String url) {
    return Splitter.on(CharMatcher.whitespace().or(CharMatcher.is(','))).trimResults()
        .omitEmptyStrings().splitToList(url).stream()
        .map(String::toLowerCase)
        .collect(toSet());
  }

  private static Set<String> enabled(Set<String> names) {
    return names.stream().filter(n -> !n.startsWith("!")).collect(toSet());
  }

  private static Set<String> disabled(Set<String> names) {
    return names.stream().filter(n -> n.startsWith("!")).map(n -> n.substring(1)).collect(toSet());
  }
}
