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

import com.google.common.collect.Iterables;
import com.google.gerrit.acceptance.SshSession;
import com.google.gerrit.acceptance.TempFileUtil;
import com.google.gerrit.acceptance.TestAccount;
import com.google.gerrit.reviewdb.client.Project;

import com.jcraft.jsch.JSch;
import com.jcraft.jsch.JSchException;
import com.jcraft.jsch.Session;

import org.eclipse.jgit.api.AddCommand;
import org.eclipse.jgit.api.CheckoutCommand;
import org.eclipse.jgit.api.CloneCommand;
import org.eclipse.jgit.api.CommitCommand;
import org.eclipse.jgit.api.Git;
import org.eclipse.jgit.api.PushCommand;
import org.eclipse.jgit.api.errors.GitAPIException;
import org.eclipse.jgit.lib.Constants;
import org.eclipse.jgit.lib.ObjectId;
import org.eclipse.jgit.lib.PersonIdent;
import org.eclipse.jgit.lib.Ref;
import org.eclipse.jgit.revwalk.RevCommit;
import org.eclipse.jgit.revwalk.RevWalk;
import org.eclipse.jgit.transport.JschConfigSessionFactory;
import org.eclipse.jgit.transport.OpenSshConfig.Host;
import org.eclipse.jgit.transport.PushResult;
import org.eclipse.jgit.transport.RefSpec;
import org.eclipse.jgit.transport.SshSessionFactory;
import org.eclipse.jgit.util.ChangeIdUtil;
import org.eclipse.jgit.util.FS;

import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.util.Properties;

public class GitUtil {

  public static void initSsh(final TestAccount a) {
    final Properties config = new Properties();
    config.put("StrictHostKeyChecking", "no");
    JSch.setConfig(config);

    // register a JschConfigSessionFactory that adds the private key as identity
    // to the JSch instance of JGit so that SSH communication via JGit can
    // succeed
    SshSessionFactory.setInstance(new JschConfigSessionFactory() {
      @Override
      protected void configure(Host hc, Session session) {
        try {
          final JSch jsch = getJSch(hc, FS.DETECTED);
          jsch.addIdentity("KeyPair", a.privateKey(),
              a.sshKey.getPublicKeyBlob(), null);
        } catch (JSchException e) {
          throw new RuntimeException(e);
        }
      }
    });
  }

  public static void createProject(SshSession s, String name)
      throws JSchException, IOException {
    createProject(s, name, null);
  }

  public static void createProject(SshSession s, String name, Project.NameKey parent)
      throws JSchException, IOException {
    createProject(s, name, parent, true);
  }

  public static void createProject(SshSession s, String name,
      Project.NameKey parent, boolean emptyCommit)
      throws JSchException, IOException {
    StringBuilder b = new StringBuilder();
    b.append("gerrit create-project");
    if (emptyCommit) {
      b.append(" --empty-commit");
    }
    b.append(" --name \"");
    b.append(name);
    b.append("\"");
    if (parent != null) {
      b.append(" --parent \"");
      b.append(parent.get());
      b.append("\"");
    }
    s.exec(b.toString());
  }

  public static Git cloneProject(String url) throws GitAPIException, IOException {
    final File gitDir = TempFileUtil.createTempDirectory();
    final CloneCommand cloneCmd = Git.cloneRepository();
    cloneCmd.setURI(url);
    cloneCmd.setDirectory(gitDir);
    return cloneCmd.call();
  }

  public static void add(Git git, String path, String content)
      throws GitAPIException, IOException {
    File f = new File(git.getRepository().getDirectory().getParentFile(), path);
    File p = f.getParentFile();
    if (!p.exists() && !p.mkdirs()) {
      throw new IOException("failed to create dir: " + p.getAbsolutePath());
    }
    FileWriter w = new FileWriter(f);
    BufferedWriter out = new BufferedWriter(w);
    try {
      out.write(content);
    } finally {
      out.close();
    }

    final AddCommand addCmd = git.add();
    addCmd.addFilepattern(path);
    addCmd.call();
  }

  public static Commit createCommit(Git git, PersonIdent i, String msg)
      throws GitAPIException, IOException {
    return createCommit(git, i, msg, null);
  }

  public static Commit amendCommit(Git git, PersonIdent i, String msg, String changeId)
      throws GitAPIException, IOException {
    msg = ChangeIdUtil.insertId(msg, ObjectId.fromString(changeId.substring(1)));
    return createCommit(git, i, msg, changeId);
  }

  private static Commit createCommit(Git git, PersonIdent i, String msg,
      String changeId) throws GitAPIException, IOException {

    final CommitCommand commitCmd = git.commit();
    commitCmd.setAmend(changeId != null);
    commitCmd.setAuthor(i);
    commitCmd.setCommitter(i);

    if (changeId == null) {
      ObjectId id = computeChangeId(git, i, msg);
      changeId = "I" + id.getName();
    }
    msg = ChangeIdUtil.insertId(msg, ObjectId.fromString(changeId.substring(1)));
    commitCmd.setMessage(msg);

    RevCommit c = commitCmd.call();
    return new Commit(c, changeId);
  }

  private static ObjectId computeChangeId(Git git, PersonIdent i, String msg)
      throws IOException {
    RevWalk rw = new RevWalk(git.getRepository());
    try {
      Ref head = git.getRepository().getRef(Constants.HEAD);
      if (head.getObjectId() != null) {
        RevCommit parent = rw.lookupCommit(head.getObjectId());
        return ChangeIdUtil.computeChangeId(parent.getTree(), parent.getId(), i, i, msg);
      } else {
        return ChangeIdUtil.computeChangeId(null, null, i, i, msg);
      }
    } finally {
      rw.release();
    }
  }

  public static void checkout(Git git, String name) throws GitAPIException {
    CheckoutCommand checkout = git.checkout();
    checkout.setName(name);
    checkout.call();
  }

  public static PushResult pushHead(Git git, String ref, boolean pushTags)
      throws GitAPIException {
    PushCommand pushCmd = git.push();
    pushCmd.setRefSpecs(new RefSpec("HEAD:" + ref));
    if (pushTags) {
      pushCmd.setPushTags();
    }
    Iterable<PushResult> r = pushCmd.call();
    return Iterables.getOnlyElement(r);
  }

  public static class Commit {
    private final RevCommit commit;
    private final String changeId;

    Commit(RevCommit commit, String changeId) {
      this.commit = commit;
      this.changeId = changeId;
    }

    public RevCommit getCommit() {
      return commit;
    }

    public String getChangeId() {
      return changeId;
    }
  }
}
