// Copyright (C) 2014 Ericsson
//
// 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.ericsson.gerrit.plugins.eventslog;

import com.google.gerrit.extensions.restapi.Url;
import com.google.gerrit.server.CurrentUser;
import com.google.inject.Inject;
import com.google.inject.Provider;
import com.google.inject.Singleton;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.IOException;
import java.io.Writer;
import java.util.HashMap;
import java.util.Map;

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

@Singleton
public class EventsRestApiServlet extends HttpServlet {
  private static final Logger log = LoggerFactory
      .getLogger(EventsRestApiServlet.class);
  private static final long serialVersionUID = 1L;

  private final EventStore store;
  private final QueryMaker queryMaker;
  private final Provider<CurrentUser> userProvider;

  @Inject
  EventsRestApiServlet(EventStore store,
      QueryMaker queryMaker,
      Provider<CurrentUser> userProvider) {
    this.store = store;
    this.queryMaker = queryMaker;
    this.userProvider = userProvider;
  }

  @Override
  protected void doGet(HttpServletRequest req, HttpServletResponse rsp)
      throws IOException, ServletException {
    if (!userProvider.get().isIdentifiedUser()) {
      rsp.sendError(HttpServletResponse.SC_UNAUTHORIZED);
      return;
    }
    rsp.setContentType("text/html");
    Map<String, String> params =
        req.getQueryString() != null ? getParameters(req) : null;
    Writer out = rsp.getWriter();

    String query = null;
    try {
      query = queryMaker.formQueryFromRequestParameters(params);
      for (String event : store.queryChangeEvents(query)) {
        out.write(event + "\n");
      }
    } catch (MalformedQueryException e) {
      log.error("Bad Request", e);
      rsp.sendError(HttpServletResponse.SC_BAD_REQUEST);
    } catch (ServiceUnavailableException e) {
      log.error("Service Unavailable", e);
      rsp.sendError(HttpServletResponse.SC_SERVICE_UNAVAILABLE);
    } catch (EventsLogException e) {
      log.error("Could not query from request parameters", e);
    }
  }

  private static Map<String, String> getParameters(HttpServletRequest req) {
    Map<String, String> params = new HashMap<>();
    for (final String pair : req.getQueryString().split("[&;]")) {
      int eq = pair.indexOf('=');
      if (0 < eq) {
        String name = pair.substring(0, eq);
        String value = pair.substring(eq + 1);

        name = Url.decode(name);
        value = Url.decode(value);
        params.put(name, value);
      }
    }
    return params;
  }
}
