// 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.common.base.Objects;
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;
  private String canonicalWebUrl;

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

@@ -762,29 +762,8 @@
 ion;
-%0Aimport java.net.URL;
 %0A%0Aim

Remove unused import