// Copyright (C) 2009 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.extensions.annotations.RequiresCapability;
import com.google.gerrit.reviewdb.client.Project;
import com.google.gerrit.server.project.ProjectCache;
import com.google.gerrit.sshd.CommandMetaData;
import com.google.gerrit.sshd.SshCommand;
import com.google.inject.Inject;

import com.googlesource.gerrit.plugins.replication.PushResultProcessing.CommandProcessing;

import org.kohsuke.args4j.Argument;
import org.kohsuke.args4j.Option;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;

@RequiresCapability(StartReplicationCapability.START_REPLICATION)
@CommandMetaData(name = "start", description = "Start replication for specific project or all projects")
final class StartCommand extends SshCommand {
  private static final Logger log = LoggerFactory.getLogger(StartCommand.class);
  private static final ReplicationStateLogger stateLog = new ReplicationStateLogger(log);
  @Option(name = "--all", usage = "push all known projects")
  private boolean all;

  @Option(name = "--url", metaVar = "PATTERN", usage = "pattern to match URL on")
  private String urlMatch;

  @Option(name = "--wait",
      usage = "wait for replication to finish before exiting")
  private boolean wait;

  @Argument(index = 0, multiValued = true, metaVar = "PROJECT", usage = "project name")
  private List<String> projectNames = new ArrayList<String>(2);

  @Inject
  private PushAll.Factory pushAllFactory;

  @Inject
  private ReplicationQueue replication;

  @Inject
  private ProjectCache projectCache;

  @Override
  protected void run() throws Failure {
    if (all && projectNames.size() > 0) {
      throw new UnloggedFailure(1, "error: cannot combine --all and PROJECT");
    }

    ReplicationState state = new ReplicationState(new CommandProcessing(this));
    Future<?> future = null;
    if (all) {
      future = pushAllFactory.create(urlMatch, state).schedule(0, TimeUnit.SECONDS);
    } else {
      for (String name : projectNames) {
        Project.NameKey key = new Project.NameKey(name);
        if (projectCache.get(key) != null) {
          replication.scheduleFullSync(key, urlMatch, state);
        } else {
          writeStdErrSync("error: '" + name + "': not a Gerrit project");
        }
      }
      state.markAllPushTasksScheduled();
    }

    if (wait) {
      if (future != null) {
        try {
          future.get();
        } catch (InterruptedException e) {
          stateLog.error("Thread was interrupted while waiting for PushAll operation to finish", e, state);
          return;
        } catch (ExecutionException e) {
          stateLog.error("An exception was thrown in PushAll operation", e, state);
          return;
        }
      }

      if (state.hasPushTask()) {
        try {
          state.waitForReplication();
        } catch (InterruptedException e) {
          writeStdErrSync("We are interrupted while waiting replication to complete");
        }
      } else {
        writeStdOutSync("Nothing to replicate");
      }
    }
  }

  public void writeStdOutSync(final String message) {
    if (wait) {
      synchronized (stdout) {
        stdout.println(message);
        stdout.flush();
      }
    }
  }

  public void writeStdErrSync(final String message) {
    if (wait) {
      synchronized (stderr) {
        stderr.println(message);
        stderr.flush();
      }
    }
  }
}
