// 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.Preconditions.checkNotNull;

import com.google.common.base.Joiner;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.Lists;

import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import javax.servlet.http.HttpServletRequest;

/** Linkifier for blocks of text such as commit message descriptions. */
public class Linkifier {
  private static final Pattern LINK_PATTERN;

  static {
    // HTTP URL regex adapted from com.google.gwtexpui.safehtml.client.SafeHtml.
    String part = "[a-zA-Z0-9$_.+!*',%;:@=?#/~<>-]";
    String httpUrl = "https?://" +
        part + "{2,}" +
        "(?:[(]" + part + "*" + "[)])*" +
        part + "*";
    String changeId = "\\bI[0-9a-f]{8,40}\\b";
    LINK_PATTERN = Pattern.compile(Joiner.on("|").join(
        "(" + httpUrl + ")",
        "(" + changeId + ")"));
  }

  private final GitilesUrls urls;

  public Linkifier(GitilesUrls urls) {
    this.urls = checkNotNull(urls, "urls");
  }

  public List<Map<String, String>> linkify(HttpServletRequest req, String message) {
    String baseGerritUrl = urls.getBaseGerritUrl(req);
    List<Map<String, String>> parsed = Lists.newArrayList();
    Matcher m = LINK_PATTERN.matcher(message);
    int last = 0;
    while (m.find()) {
      addText(parsed, message.substring(last, m.start()));
      if (m.group(1) != null) {
        // Bare URL.
        parsed.add(link(m.group(1), m.group(1)));
      } else if (m.group(2) != null) {
        if (baseGerritUrl != null) {
          // Gerrit Change-Id.
          parsed.add(link(m.group(2), baseGerritUrl + "#/q/" + m.group(2) + ",n,z"));
        } else {
          addText(parsed, m.group(2));
        }
      }
      last = m.end();
    }
    addText(parsed, message.substring(last));
    return parsed;
  }

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

  private static void addText(List<Map<String, String>> parts, String text) {
    if (text.isEmpty()) {
      return;
    }
    if (parts.isEmpty()) {
      parts.add(ImmutableMap.of("text", text));
    } else {
      Map<String, String> old = parts.get(parts.size() - 1);
      if (!old.containsKey("url")) {
        parts.set(parts.size() - 1, ImmutableMap.of("text", old.get("text") + text));
      } else {
        parts.add(ImmutableMap.of("text", text));
      }
    }
  }
}
