// 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 com.ericsson.gerrit.plugins.highavailability.Configuration;
import com.ericsson.gerrit.plugins.highavailability.cache.Constants;
import com.ericsson.gerrit.plugins.highavailability.forwarder.Forwarder;
import com.ericsson.gerrit.plugins.highavailability.forwarder.rest.HttpResponseHandler.HttpResult;
import com.google.common.base.Joiner;
import com.google.common.base.Supplier;
import com.google.gerrit.extensions.annotations.PluginName;
import com.google.gerrit.extensions.restapi.Url;
import com.google.gerrit.server.events.Event;
import com.google.gerrit.server.events.SupplierSerializer;
import com.google.gson.GsonBuilder;
import com.google.inject.Inject;
import java.io.IOException;
import javax.net.ssl.SSLException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

class RestForwarder implements Forwarder {
  private static final Logger log = LoggerFactory.getLogger(RestForwarder.class);

  private final HttpSession httpSession;
  private final String pluginRelativePath;
  private final Configuration cfg;

  @Inject
  RestForwarder(HttpSession httpClient, @PluginName String pluginName, Configuration cfg) {
    this.httpSession = httpClient;
    this.pluginRelativePath = Joiner.on("/").join("/plugins", pluginName);
    this.cfg = cfg;
  }

  @Override
  public boolean indexAccount(final int accountId) {
    return new Request("index account", accountId) {
      @Override
      HttpResult send() throws IOException {
        return httpSession.post(
            Joiner.on("/").join(pluginRelativePath, "index/account", accountId));
      }
    }.execute();
  }

  @Override
  public boolean indexChange(final String projectName, final int changeId) {
    return new Request("index change", changeId) {
      @Override
      HttpResult send() throws IOException {
        return httpSession.post(buildIndexEndpoint(projectName, changeId));
      }
    }.execute();
  }

  @Override
  public boolean deleteChangeFromIndex(final int changeId) {
    return new Request("delete change", changeId) {
      @Override
      HttpResult send() throws IOException {
        return httpSession.delete(buildIndexEndpoint(changeId));
      }
    }.execute();
  }

  @Override
  public boolean indexGroup(final String uuid) {
    return new Request("index group", uuid) {
      @Override
      HttpResult send() throws IOException {
        return httpSession.post(Joiner.on("/").join(pluginRelativePath, "index/group", uuid));
      }
    }.execute();
  }

  private String buildIndexEndpoint(int changeId) {
    return buildIndexEndpoint("", changeId);
  }

  private String buildIndexEndpoint(String projectName, int changeId) {
    String escapedProjectName = Url.encode(projectName);
    return Joiner.on("/")
        .join(pluginRelativePath, "index/change", escapedProjectName + '~' + changeId);
  }

  @Override
  public boolean send(final Event event) {
    return new Request("send event", event.type) {
      @Override
      HttpResult send() throws IOException {
        String serializedEvent =
            new GsonBuilder()
                .registerTypeAdapter(Supplier.class, new SupplierSerializer())
                .create()
                .toJson(event);
        return httpSession.post(Joiner.on("/").join(pluginRelativePath, "event"), serializedEvent);
      }
    }.execute();
  }

  @Override
  public boolean evict(final String cacheName, final Object key) {
    return new Request("invalidate cache " + cacheName, key) {
      @Override
      HttpResult send() throws IOException {
        String json = GsonParser.toJson(cacheName, key);
        return httpSession.post(Joiner.on("/").join(pluginRelativePath, "cache", cacheName), json);
      }
    }.execute();
  }

  @Override
  public boolean addToProjectList(String projectName) {
    return new Request("Update project_list, add ", projectName) {
      @Override
      HttpResult send() throws IOException {
        return httpSession.post(buildProjectListEndpoint(projectName));
      }
    }.execute();
  }

  @Override
  public boolean removeFromProjectList(String projectName) {
    return new Request("Update project_list, remove ", projectName) {
      @Override
      HttpResult send() throws IOException {
        return httpSession.delete(buildProjectListEndpoint(projectName));
      }
    }.execute();
  }

  private String buildProjectListEndpoint(String projectName) {
    return Joiner.on("/").join(pluginRelativePath, "cache", Constants.PROJECT_LIST, projectName);
  }

  private abstract class Request {
    private final String action;
    private final Object key;
    private int execCnt;

    Request(String action, Object key) {
      this.action = action;
      this.key = key;
    }

    boolean execute() {
      log.debug("Executing {} {}", action, key);
      for (; ; ) {
        try {
          execCnt++;
          tryOnce();
          log.debug("{} {} OK", action, key);
          return true;
        } catch (ForwardingException e) {
          int maxTries = cfg.http().maxTries();
          log.debug("Failed to {} {} [{}/{}]", action, key, execCnt, maxTries, e);
          if (!e.isRecoverable()) {
            log.error("{} {} failed with unrecoverable error; giving up", action, key, e);
            return false;
          }
          if (execCnt >= maxTries) {
            log.error("Failed to {} {} after {} tries; giving up", action, key, maxTries);
            return false;
          }

          log.debug("Retrying to {} {}", action, key);
          try {
            Thread.sleep(cfg.http().retryInterval());
          } catch (InterruptedException ie) {
            log.error("{} {} was interrupted; giving up", action, key, ie);
            Thread.currentThread().interrupt();
            return false;
          }
        }
      }
    }

    void tryOnce() throws ForwardingException {
      try {
        HttpResult result = send();
        if (!result.isSuccessful()) {
          throw new ForwardingException(
              true, String.format("Unable to %s %s : %s", action, key, result.getMessage()));
        }
      } catch (IOException e) {
        throw new ForwardingException(isRecoverable(e), e.getMessage(), e);
      }
    }

    abstract HttpResult send() throws IOException;

    boolean isRecoverable(IOException e) {
      return !(e instanceof SSLException);
    }
  }
}
