// 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.Config;
import org.eclipse.jgit.lib.Repository;

import com.google.gerrit.extensions.annotations.PluginName;
import com.google.gerrit.httpd.GitWebConfig;
import com.google.gerrit.reviewdb.client.Project;
import com.google.gerrit.server.config.GerritServerConfig;
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;

  @Inject
  public GitGraphServlet(@PluginName String pluginName,
      @GerritServerConfig final Config gerritConfig, GitWebConfig gitWebConfig,
      final ProjectControl.Factory projectControl,
      final GitRepositoryManager repoManager)
      throws MalformedURLException {
    URL url =
        new URL(gerritConfig.getString("gerrit", null, "canonicalWebUrl"));
    String pathPrefix = "/";
    if(url != null && url.getPath() != null) {
      pathPrefix = url.getPath();
      if(!pathPrefix.endsWith("/")) {
        pathPrefix += "/";
      }
    }
    this.canonicalPath =
        String.format("%splugins/%s/", pathPrefix, pluginName);
    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);

      String commitUrlPattern =
          gitWebConfig.getUrl()
              + gitWebConfig.getGitWebType().getRevision()
                  .replaceAll("\\$\\{project\\}", repoName)
                  .replaceAll("\\$\\{commit\\}", "{2}");
      String projectPattern =
          gitWebConfig.getUrl()
              + gitWebConfig.getGitWebType().getProject()
                  .replaceAll("\\$\\{project\\}", repoName);

      commitUrlPattern =
          (commitUrlPattern.startsWith("/") ? commitUrlPattern : "/"
              + commitUrlPattern);
      projectPattern =
          (projectPattern.startsWith("/") ? projectPattern : "/"
              + 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;
    }
  }
}
