// Copyright (C) 2017 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.analytics.test

import java.io.File
import java.util.{Date, UUID}

import com.google.gerrit.acceptance.{AbstractDaemonTest, GitUtil, _}
import com.google.gerrit.entities.Project
import com.google.gerrit.extensions.client.SubmitType
import com.google.gerrit.extensions.restapi.RestApiModule
import com.google.gerrit.server.project.ProjectResource.PROJECT_KIND
import com.google.gerrit.server.project.ProjectState
import com.google.inject.AbstractModule
import com.googlesource.gerrit.plugins.analytics.common.CommitsStatisticsCache
import com.googlesource.gerrit.plugins.analytics.{AnalyticsConfig, ContributorsResource}
import org.eclipse.jgit.api.MergeCommand.FastForwardMode
import org.eclipse.jgit.api.{Git, MergeResult}
import org.eclipse.jgit.internal.storage.file.FileRepository
import org.eclipse.jgit.junit.TestRepository
import org.eclipse.jgit.lib._
import org.eclipse.jgit.merge.MergeStrategy
import org.eclipse.jgit.revwalk.RevCommit
import org.gitective.core.CommitUtils
import org.junit.runner.Description
import org.junit.runners.model.Statement
import org.scalatest._

trait GerritTestDaemon extends BeforeAndAfterEach {
  self: Suite =>

  type TestFileRepository = TestRepository[FileRepository]

  val daemonTest = GerritTestDaemon

  protected abstract override def runTest(testName: String, args: Args): Status = {
    var status: Status = FailedStatus
    val runLambda = () => super.runTest(testName, args)

    daemonTest.testRunner.apply(new Statement() {
      override def evaluate(): Unit = {
        status = runLambda.apply()
      }
    }, Description.createTestDescription(getClass.getName, testName)).evaluate()

    status
  }

  var testFileRepository: TestFileRepository = _

  implicit var fileRepository: FileRepository = _

  implicit var fileRepositoryName: Project.NameKey = null

  protected lazy val author = newPersonIdent("Test Author", "author@test.com")

  protected lazy val committer = newPersonIdent("Test Committer", "committer@test.com")

  def newPersonIdent(name: String = "Test Person", email: String = "person@test.com", ts: Date = new Date()) =
    new PersonIdent(new PersonIdent(name, email), ts)

  override def beforeEach {
    daemonTest.setUpTestPlugin()
    fileRepositoryName = daemonTest.newProject(testSpecificRepositoryName)
    fileRepository = daemonTest.getRepository(fileRepositoryName)
    testFileRepository = GitUtil.newTestRepository(fileRepository)
  }

  protected def testSpecificRepositoryName = "git-test-case-" + UUID.randomUUID().toString

  implicit class PimpedGitRepository(repo: TestFileRepository) {

    def branch(name: String, startPoint: String): Ref =
      repo.git.branchCreate.setName(name).setStartPoint(startPoint).call

    def gitClone: TestFileRepository = {
      val TmpDir = System.getProperty("java.io.tmpdir")
      val clonedRepository = Git.cloneRepository
        .setDirectory(new File(s"$TmpDir/${testSpecificRepositoryName}_clone"))
        .setURI(repo.getRepository.getDirectory.toURI.toString)
        .call()
        .getRepository.asInstanceOf[FileRepository]

      GitUtil.newTestRepository(clonedRepository)
    }

    def commitFile(path: String, content: String, author: PersonIdent = author, committer: PersonIdent = committer, branch: String = Constants.MASTER, message: String = ""): RevCommit =
      repo.branch(branch).commit()
        .add(path, content)
        .author(author)
        .committer(committer)
        .message(message)
        .create

    def commitFiles(files: Iterable[(String, String)], author: PersonIdent = author, committer: PersonIdent = committer, branch: String = Constants.MASTER, message: String = ""): RevCommit = {
      val commit = repo.branch(branch).commit()
        .author(author)
        .committer(committer)
        .message(message)

      files.foldLeft(commit) {
        (commit, fileAndContent) => commit.add(fileAndContent._1, fileAndContent._2)
      }.create()
    }

    def mergeCommitFile(fileName: String, content: String, author: PersonIdent = author, committer: PersonIdent = committer): MergeResult = {
      val currentBranch = repo.getRepository.getFullBranch
      val tmpBranch = repo.branch("tmp", currentBranch)
      try {
        repo.commitFile(fileName, content, branch = tmpBranch.getName, author = author, committer = committer)
        repo.mergeBranch(tmpBranch.getName, withCommit = true)
      } finally {
        repo.git.branchDelete().setBranchNames(tmpBranch.getName).setForce(true).call.get(0)
      }
    }

    def mergeBranch(branch: String, withCommit: Boolean, message: String = "merging branch"): MergeResult = {
      repo.git.merge.setStrategy(MergeStrategy.RESOLVE)
        .include(CommitUtils.getRef(repo.getRepository, branch))
        .setCommit(withCommit)
        .setFastForward(FastForwardMode.NO_FF)
        .setMessage(message)
        .call
    }

    def push =
      repo.git.push.setPushAll.call
  }
}

@TestPlugin(
  name = "analytics",
  sysModule = "com.googlesource.gerrit.plugins.analytics.test.GerritTestDaemon$TestModule"
)
object GerritTestDaemon extends LightweightPluginDaemonTest {
  baseConfig = new Config()
  AbstractDaemonTest.temporaryFolder.create()
  tempDataDir.create()

  def newProject(nameSuffix: String, emptyCommit: Boolean = false) = {
    resourcePrefix = ""
    super.createProjectOverAPI(nameSuffix, allProjects, emptyCommit, SubmitType.MERGE_IF_NECESSARY)
  }

  def reloadProject(projectName: Project.NameKey): Option[ProjectState] = {
    projectCache.evict(projectName)
    Option(projectCache.get(projectName).orElse(null))
  }

  def getRepository(projectName: Project.NameKey): FileRepository =
    repoManager.openRepository(projectName).asInstanceOf[FileRepository]

  def adminAuthor = admin.newIdent

  def getInstance[T](clazz: Class[T]): T =
    plugin.getSysInjector.getInstance(clazz)

  def getCanonicalWebUrl: String = canonicalWebUrl.get()

  def restSession: RestSession = adminRestSession

  class TestModule extends AbstractModule {
    override def configure(): Unit = {
      bind(classOf[CommitsStatisticsCache]).to(classOf[CommitsStatisticsNoCache])
      bind(classOf[AnalyticsConfig]).toInstance(TestAnalyticsConfig)
      install(new RestApiModule() {
        override protected def configure() = {
          get(PROJECT_KIND, "contributors").to(classOf[ContributorsResource])
        }
      })
    }
  }
}