// Copyright (C) 2012 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.googlesource.gerrit.plugins.branchnetwork.canvas;

import java.io.IOException;
import java.io.PrintWriter;
import java.net.MalformedURLException;
import java.net.URL;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.eclipse.jgit.errors.RepositoryNotFoundException;
import org.eclipse.jgit.lib.Repository;

import com.google.gerrit.common.data.GitWebType;
import com.google.gerrit.extensions.annotations.PluginCanonicalWebUrl;
import com.google.gerrit.httpd.GitWebConfig;
import com.google.gerrit.reviewdb.client.Project;
import com.google.gerrit.server.git.GitRepositoryManager;
import com.google.gerrit.server.project.NoSuchProjectException;
import com.google.gerrit.server.project.ProjectControl;
import com.google.gerrit.server.project.ProjectControl.Factory;
import com.google.inject.Inject;
import com.google.inject.Singleton;

@Singleton
public class GitGraphServlet extends HttpServlet {

  private static final long serialVersionUID = -822406714154950673L;
  private static final int PROGRESS_BAR_WIDTH = 208;
  private static final int PROGRESS_BAR_HEIGHT = 13;
  private String canonicalPath;
  private Factory projectControl;
  private GitRepositoryManager repoManager;
  private GitWebConfig gitWebConfig;
  private String pluginCanonicalWebUrl;

  @Inject
  public GitGraphServlet(@PluginCanonicalWebUrl String url,
      GitWebConfig gitWebConfig,
      final ProjectControl.Factory projectControl,
      final GitRepositoryManager repoManager)
      throws MalformedURLException {
    this.canonicalPath = new URL(url).getPath();
    this.pluginCanonicalWebUrl =
        url.substring(0, url.length() - (canonicalPath.length() - 1));
    this.projectControl = projectControl;
    this.repoManager = repoManager;
    this.gitWebConfig = gitWebConfig;
  }

  @Override
  protected void doGet(HttpServletRequest req, HttpServletResponse resp)
      throws ServletException, IOException {
    resp.setContentType("text/html;charset=UTF-8");
    PrintWriter out = resp.getWriter();

    try {
      String repoName = req.getParameter("p");
      if (repoName == null) {
        resp.sendRedirect("Documentation/index.html");
        return;
      }

      boolean naked = req.getParameter("naked") != null;
      int width = getParam(req, "width", 920);
      int height = getParam(req, "height", 600);

      if (repoName.endsWith(".git")) {
        repoName = repoName.substring(0, repoName.length() - 4);
      }

      final Project.NameKey nameKey = new Project.NameKey(repoName);
      try {
        projectControl.validateFor(nameKey);
      } catch (NoSuchProjectException e) {
        resp.sendError(HttpServletResponse.SC_NOT_FOUND);
        return;
      }

      Repository repo = null;
      try {
        repo = repoManager.openRepository(nameKey);
      } catch (RepositoryNotFoundException e) {
        getServletContext().log("Cannot open repository", e);
        resp.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
        return;
      } finally {
        if (repo != null) {
          repo.close();
        }
      }

      String networkMetaUrl =
          String.format("%1$snetwork_meta/%2$s/", canonicalPath, repoName);
      String networkDataChunkUrl =
          String.format("%1$snetwork_data_chunk/%2$s/?nethash=", canonicalPath,
              repoName);

      GitWebType type = gitWebConfig.getGitWebType();
      if (type == null) {
        out.println("<html>ERROR: invalid gitweb configuration</html>");
      } else {
        String commitUrlPattern =
            gitWebConfig.getUrl()
                + type.getRevision()
                    .replaceAll("\\$\\{project\\}", repoName)
                    .replaceAll("\\$\\{commit\\}", "{2}");
        String projectPattern =
            gitWebConfig.getUrl()
                + type.getProject()
                    .replaceAll("\\$\\{project\\}", repoName);

        commitUrlPattern =
            (commitUrlPattern.startsWith("/") ? commitUrlPattern : pluginCanonicalWebUrl
                + commitUrlPattern);
        projectPattern =
            (projectPattern.startsWith("/") ? projectPattern : pluginCanonicalWebUrl
                + projectPattern);

        String header =
            "<html>\n" + "<head>\n" + "<style type=\"text/css\">\n"
                + "div#progress\n" + "{\n" + "position:absolute;\n" + "left:"
                + (width - PROGRESS_BAR_WIDTH) / 2
                + "px;\n"
                + "top:"
                + (height - PROGRESS_BAR_HEIGHT) / 2
                + "px;\n"
                + "z-index:-1;\n"
                + "}\n"
                + "div#graph\n"
                + "{\n"
                + "position:absolute;\n"
                + "left:0px;\n"
                + "top:0px;\n"
                + "z-index:0;\n"
                + "}\n"
                + "</style>\n"
                + "</head>\n"
                + "<body>\n"
                + "<div id=\"progress\" >"
                + "<img src=\""
                + canonicalPath
                + "static/progress_bar.gif\" />"
                + "</div>"
                + "<div id=\"graph\">";
        String javaScript =
            "<script type=\"text/javascript\" src=\"" + canonicalPath
                + "static/jquery-1.4.2.min.js\"></script>\n"
                + "<script type=\"text/javascript\" src=\"" + canonicalPath
                + "static/network.js\"></script>\n"
                + "<script type=\"text/javascript\">"
                + "$(document).ready( function() {\n"
                + "new NetworkCanvas('network-canvas', " + width + ", " + height
                + " , null, null, null,\n" + "'" + commitUrlPattern + "',\n"
                + "'" + projectPattern + "',\n" + "'" + networkMetaUrl + "',\n"
                + "'" + networkDataChunkUrl + "');\n" + "});\n" + "</script>\n";
        String canvas =
            "<canvas id=\"network-canvas\" width=\"" + width + "\" height=\""
                + height + "\" style=\"cursor: default; \"></canvas>";
        String footer = "</div>" + "</body>\n" + "</html>\n";
        out.println(naked ? (javaScript + canvas)
            : (header + javaScript + canvas + footer));
      }
    } finally {
      out.close();
    }
  }

  private int getParam(HttpServletRequest req, String name, int defValue) {
    String value = req.getParameter(name);
    if (value != null) {
      return Integer.parseInt(value);
    } else {
      return defValue;
    }
  }
}
