// Copyright (C) 2010 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.google.gerrit.httpd.raw;

import static com.google.gerrit.httpd.HtmlDomUtil.compress;
import static com.google.gerrit.httpd.HtmlDomUtil.newDocument;
import static com.google.gerrit.httpd.HtmlDomUtil.toUTF8;
import static javax.servlet.http.HttpServletResponse.SC_NOT_FOUND;
import static org.eclipse.jgit.util.HttpSupport.HDR_CACHE_CONTROL;
import static org.eclipse.jgit.util.HttpSupport.HDR_EXPIRES;
import static org.eclipse.jgit.util.HttpSupport.HDR_PRAGMA;

import com.google.gerrit.common.Version;
import com.google.gerrit.server.tools.ToolsCatalog;
import com.google.gerrit.server.tools.ToolsCatalog.Entry;
import com.google.gwtjsonrpc.server.RPCServletUtils;
import com.google.inject.Inject;
import com.google.inject.Singleton;

import org.w3c.dom.Document;
import org.w3c.dom.Element;

import java.io.IOException;
import java.io.OutputStream;

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

/** Sends the client side tools we keep within our software. */
@Singleton
public class ToolServlet extends HttpServlet {
  private static final long serialVersionUID = 1L;
  private final ToolsCatalog toc;

  @Inject
  ToolServlet(ToolsCatalog toc) {
    this.toc = toc;
  }

  @Override
  protected void doGet(HttpServletRequest req, HttpServletResponse rsp)
      throws IOException {
    Entry ent = toc.get(req.getPathInfo());
    if (ent == null) {
      rsp.sendError(SC_NOT_FOUND);
      return;
    }

    switch (ent.getType()) {
      case FILE:
        doGetFile(ent, req, rsp);
        break;

      case DIR:
        doGetDirectory(ent, req, rsp);
        break;

      default:
        rsp.sendError(SC_NOT_FOUND);
        break;
    }
  }

  private void doGetFile(Entry ent, HttpServletRequest req,
      HttpServletResponse rsp) throws IOException {
    byte[] tosend = ent.getBytes();

    rsp.setDateHeader(HDR_EXPIRES, 0L);
    rsp.setHeader(HDR_PRAGMA, "no-cache");
    rsp.setHeader(HDR_CACHE_CONTROL, "no-cache, must-revalidate");
    rsp.setContentType("application/octet-stream");
    rsp.setContentLength(tosend.length);
    final OutputStream out = rsp.getOutputStream();
    try {
      out.write(tosend);
    } finally {
      out.close();
    }
  }

  private void doGetDirectory(Entry ent, HttpServletRequest req,
      HttpServletResponse rsp) throws IOException {
    String path = "/tools/" + ent.getPath();
    Document page = newDocument();

    Element html = page.createElement("html");
    Element head = page.createElement("head");
    Element title = page.createElement("title");
    Element body = page.createElement("body");

    page.appendChild(html);
    html.appendChild(head);
    html.appendChild(body);
    head.appendChild(title);

    title.setTextContent("Gerrit Code Review - " + path);

    Element h1 = page.createElement("h1");
    h1.setTextContent(title.getTextContent());
    body.appendChild(h1);

    Element ul = page.createElement("ul");
    body.appendChild(ul);

    for (Entry e : ent.getChildren()) {
      String name = e.getName();
      if (e.getType() == Entry.Type.DIR && !name.endsWith("/")) {
        name += "/";
      }

      Element li = page.createElement("li");
      Element a = page.createElement("a");
      a.setAttribute("href", name);
      a.setTextContent(name);
      li.appendChild(a);
      ul.appendChild(li);
    }

    body.appendChild(page.createElement("hr"));

    Element footer = page.createElement("p");
    footer.setAttribute("style", "text-align: right; font-style: italic");
    footer.setTextContent("Powered by Gerrit Code Review "
        + Version.getVersion());
    body.appendChild(footer);

    byte[] tosend = toUTF8(page);
    if (RPCServletUtils.acceptsGzipEncoding(req)) {
      rsp.setHeader("Content-Encoding", "gzip");
      tosend = compress(tosend);
    }

    rsp.setDateHeader(HDR_EXPIRES, 0L);
    rsp.setHeader(HDR_PRAGMA, "no-cache");
    rsp.setHeader(HDR_CACHE_CONTROL, "no-cache, must-revalidate");
    rsp.setContentType("text/html");
    rsp.setCharacterEncoding("UTF-8");
    rsp.setContentLength(tosend.length);
    final OutputStream out = rsp.getOutputStream();
    try {
      out.write(tosend);
    } finally {
      out.close();
    }
  }
}
