// 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.rpc.change;

import com.google.gerrit.server.query.change.QueryProcessor;
import com.google.gerrit.server.query.change.QueryProcessor.OutputFormat;
import com.google.gson.Gson;
import com.google.inject.Inject;
import com.google.inject.Provider;
import com.google.inject.Singleton;

import java.io.IOException;

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

@Singleton
public class DeprecatedChangeQueryServlet extends HttpServlet {
  private static final long serialVersionUID = 1L;
  private final Provider<QueryProcessor> processor;

  @Inject
  DeprecatedChangeQueryServlet(Provider<QueryProcessor> processor) {
    this.processor = processor;
  }

  @Override
  protected void doGet(HttpServletRequest req, HttpServletResponse rsp)
      throws IOException {
    rsp.setContentType("text/json");
    rsp.setCharacterEncoding("UTF-8");

    QueryProcessor p = processor.get();
    OutputFormat format = OutputFormat.JSON;
    try {
      format = OutputFormat.valueOf(get(req, "format", format.toString()));
    } catch (IllegalArgumentException err) {
      error(rsp, "invalid format");
      return;
    }

    switch (format) {
      case JSON:
        rsp.setContentType("text/json");
        rsp.setCharacterEncoding("UTF-8");
        break;

      case TEXT:
        rsp.setContentType("text/plain");
        rsp.setCharacterEncoding("UTF-8");
        break;

      default:
        error(rsp, "invalid format");
        return;
    }

    p.setIncludeComments(get(req, "comments", false));
    p.setIncludeCurrentPatchSet(get(req, "current-patch-set", false));
    p.setIncludePatchSets(get(req, "patch-sets", false));
    p.setIncludeApprovals(get(req, "all-approvals", false));
    p.setIncludeFiles(get(req, "files", false));
    p.setOutput(rsp.getOutputStream(), format);
    p.query(get(req, "q", "status:open"));
  }

  private static void error(HttpServletResponse rsp, String message)
      throws IOException {
    ErrorMessage em = new ErrorMessage();
    em.message = message;

    ServletOutputStream out = rsp.getOutputStream();
    try {
      out.write(new Gson().toJson(em).getBytes("UTF-8"));
      out.write('\n');
      out.flush();
    } finally {
      out.close();
    }
  }

  private static String get(HttpServletRequest req, String name, String val) {
    String v = req.getParameter(name);
    if (v == null || v.isEmpty()) {
      return val;
    }
    return v;
  }

  private static boolean get(HttpServletRequest req, String name, boolean val) {
    String v = req.getParameter(name);
    if (v == null || v.isEmpty()) {
      return val;
    }
    return "true".equalsIgnoreCase(v);
  }

  public static class ErrorMessage {
    public final String type = "error";
    public String message;
  }
}
