// Copyright (C) 2013 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.googlesource.gerrit.plugins.replication;

import com.google.gerrit.server.PluginUser;
import com.google.gerrit.server.account.GroupBackend;
import com.google.gerrit.server.config.SitePaths;
import com.google.gerrit.server.git.GitRepositoryManager;
import com.google.gerrit.server.git.WorkQueue;
import com.google.inject.Inject;
import com.google.inject.Injector;
import com.google.inject.Singleton;

import com.googlesource.gerrit.plugins.replication.RemoteSiteUser;

import org.eclipse.jgit.errors.ConfigInvalidException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.IOException;
import java.util.List;

@Singleton
public class AutoReloadConfigDecorator implements ReplicationConfig {
  private static final Logger log = LoggerFactory
      .getLogger(AutoReloadConfigDecorator.class);
  private ReplicationFileBasedConfig currentConfig;
  private long currentConfigTs;

  private final Injector injector;
  private final SitePaths site;
  private final RemoteSiteUser.Factory remoteSiteUserFactory;
  private final PluginUser pluginUser;
  private final GitRepositoryManager gitRepositoryManager;
  private final GroupBackend groupBackend;
  private final WorkQueue workQueue;

  @Inject
  public AutoReloadConfigDecorator(Injector injector, SitePaths site,
      RemoteSiteUser.Factory ruf, PluginUser pu,
      GitRepositoryManager grm, GroupBackend gb,
      WorkQueue workQueue) throws ConfigInvalidException,
      IOException {
    this.injector = injector;
    this.site = site;
    this.remoteSiteUserFactory = ruf;
    this.pluginUser = pu;
    this.gitRepositoryManager = grm;
    this.groupBackend = gb;
    this.currentConfig = loadConfig();
    this.currentConfigTs = currentConfig.getCfgPath().lastModified();
    this.workQueue = workQueue;
  }

  private ReplicationFileBasedConfig loadConfig()
      throws ConfigInvalidException, IOException {
    return new ReplicationFileBasedConfig(injector, site,
        remoteSiteUserFactory, pluginUser, gitRepositoryManager,
        groupBackend);
  }

  private synchronized boolean isAutoReload() {
    return currentConfig.getConfig().getBoolean("gerrit", "autoReload", false);
  }

  @Override
  public synchronized List<Destination> getDestinations() {
    reloadIfNeeded();
    return currentConfig.getDestinations();
  }

  private void reloadIfNeeded() {
    if (isAutoReload()
        && currentConfig.getCfgPath().lastModified() > currentConfigTs) {
      try {
        ReplicationFileBasedConfig newConfig = loadConfig();
        newConfig.startup(workQueue);
        int discarded = currentConfig.shutdown();

        this.currentConfig = newConfig;
        this.currentConfigTs = currentConfig.getCfgPath().lastModified();
        log.info("Configuration reloaded: "
            + currentConfig.getDestinations().size() + " destinations, "
            + discarded + " replication events discarded");

      } catch (Exception e) {
        log.error(
            "Cannot reload replication configuration: keeping existing settings",
            e);
        return;
      }
    }
  }

  @Override
  public synchronized boolean isReplicateAllOnPluginStart() {
    return currentConfig.isReplicateAllOnPluginStart();
  }

  @Override
  public synchronized boolean isDefaultForceUpdate() {
    return currentConfig.isDefaultForceUpdate();
  }

  @Override
  public synchronized boolean isEmpty() {
    return currentConfig.isEmpty();
  }

  @Override
  public synchronized int shutdown() {
    return currentConfig.shutdown();
  }

  @Override
  public synchronized void startup(WorkQueue workQueue) {
    currentConfig.startup(workQueue);
  }
}
