// 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.gwt.user.server.rpc.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();
    }
  }
}
