// Copyright (C) 2015 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.highavailability.forwarder.rest;

import static javax.servlet.http.HttpServletResponse.SC_BAD_REQUEST;
import static javax.servlet.http.HttpServletResponse.SC_NO_CONTENT;

import com.ericsson.gerrit.plugins.highavailability.cache.Constants;
import com.ericsson.gerrit.plugins.highavailability.forwarder.Context;
import com.google.common.annotations.VisibleForTesting;
import com.google.common.base.Splitter;
import com.google.common.cache.Cache;
import com.google.gerrit.extensions.registration.DynamicMap;
import com.google.inject.Inject;
import com.google.inject.Singleton;
import java.io.IOException;
import java.util.List;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

@Singleton
class CacheRestApiServlet extends HttpServlet {
  private static final int CACHENAME_INDEX = 1;
  private static final long serialVersionUID = -1L;
  private static final Logger logger = LoggerFactory.getLogger(CacheRestApiServlet.class);

  private final DynamicMap<Cache<?, ?>> cacheMap;

  @Inject
  CacheRestApiServlet(DynamicMap<Cache<?, ?>> cacheMap) {
    this.cacheMap = cacheMap;
  }

  @Override
  protected void doPost(HttpServletRequest req, HttpServletResponse rsp)
      throws IOException, ServletException {
    rsp.setContentType("text/plain");
    rsp.setCharacterEncoding("UTF-8");
    try {
      List<String> params = Splitter.on('/').splitToList(req.getPathInfo());
      String cacheName = params.get(CACHENAME_INDEX);
      String json = req.getReader().readLine();
      Object key = GsonParser.fromJson(cacheName, json);
      CacheParameters cacheKey = getCacheParameters(cacheName);
      Cache<?, ?> cache = cacheMap.get(cacheKey.pluginName, cacheKey.cacheName);
      if (cache == null) {
        String msg = String.format("cache %s not found", cacheName);
        logger.error("Failed to process eviction request: {}", msg);
        sendError(rsp, SC_BAD_REQUEST, msg);
      } else {
        Context.setForwardedEvent(true);
        evictCache(cache, cacheKey.cacheName, key);
        rsp.setStatus(SC_NO_CONTENT);
      }
    } catch (IOException e) {
      logger.error("Failed to process eviction request: {}", e.getMessage(), e);
      sendError(rsp, SC_BAD_REQUEST, e.getMessage());
    } finally {
      Context.unsetForwardedEvent();
    }
  }

  @VisibleForTesting
  public static class CacheParameters {
    public final String pluginName;
    public final String cacheName;

    public CacheParameters(String pluginName, String cacheName) {
      this.pluginName = pluginName;
      this.cacheName = cacheName;
    }
  }

  @VisibleForTesting
  public static CacheParameters getCacheParameters(String cache) {
    int dot = cache.indexOf(".");
    if (dot > 0) {
      return new CacheParameters(cache.substring(0, dot), cache.substring(dot + 1));
    }
    return new CacheParameters(Constants.GERRIT, cache);
  }

  private static void sendError(HttpServletResponse rsp, int statusCode, String message) {
    try {
      rsp.sendError(statusCode, message);
    } catch (IOException e) {
      logger.error("Failed to send error messsage: {}", e.getMessage(), e);
    }
  }

  private void evictCache(Cache<?, ?> cache, String cacheName, Object key) {
    if (Constants.PROJECT_LIST.equals(cacheName)) {
      // One key is holding the list of projects
      cache.invalidateAll();
      logger.debug("Invalidated cache {}", cacheName);
    } else {
      cache.invalidate(key);
      logger.debug("Invalidated cache {}[{}]", cacheName, key);
    }
  }
}
