// 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.google.gerrit.git;

import com.google.gerrit.client.reviewdb.Project;
import com.google.gerrit.server.GerritServer;
import com.google.gwtjsonrpc.server.XsrfException;
import com.google.gwtorm.client.OrmException;

import com.jcraft.jsch.Session;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.spearce.jgit.errors.NotSupportedException;
import org.spearce.jgit.errors.TransportException;
import org.spearce.jgit.lib.NullProgressMonitor;
import org.spearce.jgit.lib.Repository;
import org.spearce.jgit.lib.RepositoryConfig;
import org.spearce.jgit.transport.OpenSshConfig;
import org.spearce.jgit.transport.PushResult;
import org.spearce.jgit.transport.RefSpec;
import org.spearce.jgit.transport.RemoteConfig;
import org.spearce.jgit.transport.RemoteRefUpdate;
import org.spearce.jgit.transport.SshConfigSessionFactory;
import org.spearce.jgit.transport.SshSessionFactory;
import org.spearce.jgit.transport.Transport;
import org.spearce.jgit.transport.URIish;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.net.URISyntaxException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.TimeUnit;

public class PushQueue {
  private static final Logger log = LoggerFactory.getLogger(PushQueue.class);
  private static final int startDelay = 15; // seconds
  private static List<RemoteConfig> configs;
  private static final Map<URIish, PushOp> active =
      new HashMap<URIish, PushOp>();

  static {
    // Install our own factory which always runs in batch mode, as we
    // have no UI available for interactive prompting.
    //
    SshSessionFactory.setInstance(new SshConfigSessionFactory() {
      @Override
      protected void configure(OpenSshConfig.Host hc, Session session) {
        // Default configuration is batch mode.
      }
    });
  }

  public static void scheduleUpdate(final Project.NameKey project,
      final String ref) {
    for (final RemoteConfig srcConf : allConfigs()) {
      RefSpec spec = null;
      for (final RefSpec s : srcConf.getPushRefSpecs()) {
        if (s.matchSource(ref)) {
          spec = s;
          break;
        }
      }
      if (spec == null) {
        continue;
      }

      for (URIish uri : srcConf.getURIs()) {
        uri = uri.setPath(replace(uri.getPath(), "name", project.get()));
        scheduleImp(project, ref, srcConf, uri);
      }
    }
  }

  private static synchronized void scheduleImp(final Project.NameKey project,
      final String ref, final RemoteConfig srcConf, final URIish uri) {
    PushOp e = active.get(uri);
    if (e == null) {
      final PushOp newOp = new PushOp(project.get(), srcConf, uri);
      WorkQueue.schedule(new Runnable() {
        public void run() {
          try {
            pushImpl(newOp);
          } catch (RuntimeException e) {
            log.error("Unexpected error during replication", e);
          } catch (Error e) {
            log.error("Unexpected error during replication", e);
          }
        }
      }, startDelay, TimeUnit.SECONDS);
      active.put(uri, newOp);
      e = newOp;
    }
    e.delta.add(ref);
  }

  private static void pushImpl(final PushOp op) {
    removeFromActive(op);
    final Repository db;
    try {
      db = GerritServer.getInstance().getRepositoryCache().get(op.projectName);
    } catch (OrmException e) {
      log.error("Cannot open repository cache", e);
      return;
    } catch (XsrfException e) {
      log.error("Cannot open repository cache", e);
      return;
    } catch (InvalidRepositoryException e) {
      log.error("Cannot replicate " + op.projectName, e);
      return;
    }

    final ArrayList<RemoteRefUpdate> cmds = new ArrayList<RemoteRefUpdate>();
    try {
      for (final String ref : op.delta) {
        final String src = ref;
        RefSpec spec = null;
        for (final RefSpec s : op.config.getPushRefSpecs()) {
          if (s.matchSource(src)) {
            spec = s.expandFromSource(src);
            break;
          }
        }
        if (spec == null) {
          continue;
        }

        // If the ref still exists locally, send it, else delete it.
        //
        final String srcexp = db.resolve(src) != null ? src : null;
        final String dst = spec.getDestination();
        final boolean force = spec.isForceUpdate();
        cmds.add(new RemoteRefUpdate(db, srcexp, dst, force, null, null));
      }
    } catch (IOException e) {
      log.error("Cannot replicate " + op.projectName, e);
      return;
    }

    final Transport tn;
    try {
      tn = Transport.open(db, op.uri);
      tn.applyConfig(op.config);
    } catch (NotSupportedException e) {
      log.error("Cannot replicate to " + op.uri, e);
      return;
    }

    final PushResult res;
    try {
      res = tn.push(NullProgressMonitor.INSTANCE, cmds);
    } catch (NotSupportedException e) {
      log.error("Cannot replicate to " + op.uri, e);
      return;
    } catch (TransportException e) {
      log.error("Cannot replicate to " + op.uri, e);
      return;
    } finally {
      try {
        tn.close();
      } catch (Throwable e2) {
        log.warn("Unexpected error while closing " + op.uri, e2);
      }
    }

    for (final RemoteRefUpdate u : res.getRemoteUpdates()) {
      switch (u.getStatus()) {
        case OK:
        case UP_TO_DATE:
        case NON_EXISTING:
          break;

        case NOT_ATTEMPTED:
        case AWAITING_REPORT:
        case REJECTED_NODELETE:
        case REJECTED_NONFASTFORWARD:
        case REJECTED_REMOTE_CHANGED:
          log.error("Failed replicate of " + u.getRemoteName() + " to "
              + op.uri + ": status " + u.getStatus().name());
          break;

        case REJECTED_OTHER_REASON:
          log.error("Failed replicate of " + u.getRemoteName() + " to "
              + op.uri + ", reason: " + u.getMessage());
          break;
      }
    }
  }

  private static synchronized void removeFromActive(final PushOp op) {
    active.remove(op.uri);
  }

  private static String replace(final String pat, final String key,
      final String val) {
    final int n = pat.indexOf("${" + key + "}");
    return pat.substring(0, n) + val + pat.substring(n + 3 + key.length());
  }

  private static synchronized List<RemoteConfig> allConfigs() {
    if (configs == null) {
      final File path;
      try {
        final GerritServer gs = GerritServer.getInstance();
        path = gs.getSitePath();
        if (path == null || gs.getRepositoryCache() == null) {
          return Collections.emptyList();
        }
      } catch (OrmException e) {
        return Collections.emptyList();
      } catch (XsrfException e) {
        return Collections.emptyList();
      }

      final File cfgFile = new File(path, "replication.config");
      final RepositoryConfig cfg = new RepositoryConfig(null, cfgFile);
      try {
        cfg.load();
        final ArrayList<RemoteConfig> r = new ArrayList<RemoteConfig>();
        for (final RemoteConfig c : RemoteConfig.getAllRemoteConfigs(cfg)) {
          if (c.getURIs().isEmpty()) {
            continue;
          }

          for (final URIish u : c.getURIs()) {
            if (u.getPath() == null || !u.getPath().contains("${name}")) {
              final String s = u.toString();
              throw new URISyntaxException(s, "No ${name}");
            }
          }

          if (c.getPushRefSpecs().isEmpty()) {
            RefSpec spec = new RefSpec();
            spec = spec.setSourceDestination("refs/*", "refs/*");
            spec = spec.setForceUpdate(true);
            c.addPushRefSpec(spec);
          }

          r.add(c);
        }
        configs = Collections.unmodifiableList(r);
      } catch (FileNotFoundException e) {
        log.warn("No " + cfgFile + "; not replicating");
        configs = Collections.emptyList();
      } catch (IOException e) {
        log.error("Can't read " + cfgFile, e);
        return Collections.emptyList();
      } catch (URISyntaxException e) {
        log.error("Invalid URI in " + cfgFile, e);
        return Collections.emptyList();
      }
    }
    return configs;
  }

  private static class PushOp {
    final Set<String> delta = new HashSet<String>();
    final String projectName;
    final RemoteConfig config;
    final URIish uri;

    PushOp(final String d, final RemoteConfig c, final URIish u) {
      projectName = d;
      config = c;
      uri = u;
    }
  }
}
