// 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.util.Date

import com.googlesource.gerrit.plugins.analytics.common.{AggregatedHistogramFilterByDates, AggregatedUserCommitActivity, AggregationStrategy}
import org.eclipse.jgit.revwalk.RevCommit
import org.gitective.core.CommitFinder
import org.scalatest.{FlatSpec, Inspectors, Matchers}
import AggregationStrategy._

class AggregationSpec extends FlatSpec with Matchers with GitTestCase with Inspectors {

  import com.googlesource.gerrit.plugins.analytics.common.DateConversions._

  def commit(committer: String, when: String, content: String): RevCommit = {
    val date = new Date(isoStringToLongDate(when))
    val person = newPersonIdent(committer, committer, date)
    add("afile.txt", content, author = person, committer = author)
  }

  def aggregateBy(strategy: AggregationStrategy) = {
    val filter = new AggregatedHistogramFilterByDates(aggregationStrategy = strategy)
    new CommitFinder(testRepo).setFilter(filter).find
    filter.getHistogram.getAggregatedUserActivity
  }

  "AggregatedHistogramFilter by email and year" should "aggregate two commits from the same author the same year" in {
    commit("john", "2017-08-01", "first commit")
    commit("john", "2017-10-05", "second commit")

    val userActivity = aggregateBy(EMAIL_YEAR)

    userActivity should have size 1
    userActivity.head.getCount should be(2)
    userActivity.head.email should be("john")
  }

  it should "keep as separate rows activity from the same author on two different year" in {
    commit("john", "2017-08-01", "first commit")
    commit("john", "2018-09-01", "second commit")

    val userActivity = aggregateBy(EMAIL_YEAR)

    userActivity should have size 2
    forAll(userActivity) {
      activity => {
        activity.email should be("john")
        activity.getCount should be(1)
        1
      }
    }
  }

  it should "keep as separate rows activity from two different authors on the same year" in {
    commit("john", "2017-08-01", "first commit")
    commit("bob", "2017-12-05", "second commit")

    val userActivity = aggregateBy(EMAIL_YEAR)

    userActivity should have size 2
    userActivity.map(_.email) should contain allOf("john", "bob")
    forAll(userActivity) {
      _.getCount should be(1)
    }
  }

  "AggregatedHistogramFilter by email and month" should "aggregate two commits from the same author the same month" in {
    commit("john", "2017-08-01", "first commit")
    commit("john", "2017-08-05", "second commit")

    val userActivity = aggregateBy(EMAIL_MONTH)

    userActivity should have size 1
    userActivity.head.getCount should be(2)
    userActivity.head.email should be("john")
  }

  it should "keep as separate rows activity from the same author on two different months" in {
    commit("john", "2017-08-01", "first commit")
    commit("john", "2017-09-01", "second commit")

    val userActivity = aggregateBy(EMAIL_MONTH)

    userActivity should have size 2
    forAll(userActivity) {
      activity => {
        activity.email should be("john")
        activity.getCount should be(1)
        1
      }
    }
  }

  it should "keep as separate rows activity from two different authors on the same month" in {
    commit("john", "2017-08-01", "first commit")
    commit("bob", "2017-08-05", "second commit")

    val userActivity = aggregateBy(EMAIL_MONTH)

    userActivity should have size 2
    userActivity.map(_.email) should contain allOf("john", "bob")
    forAll(userActivity) {
      _.getCount should be(1)
    }
  }

  "AggregatedHistogramFilter by email and day" should "aggregate two commits of the same author the same day" in {
    commit("john", "2017-08-01", "first commit")
    commit("john", "2017-08-01", "second commit")

    val userActivity = aggregateBy(EMAIL_DAY)

    userActivity should have size 1
    userActivity.head.getCount should be(2)
    userActivity.head.email should be("john")
  }

  it should "keep as separate rows activity from the same author on two different days" in {
    commit("john", "2017-08-01", "first commit")
    commit("john", "2017-08-02", "second commit")

    val userActivity = aggregateBy(EMAIL_DAY)

    userActivity should have size 2
    forAll(userActivity) {
      activity => {
        activity.email should be("john")
        activity.getCount should be
        1
      }
    }
  }

  it should "keep as separate rows activity from two different authors on the same day" in {
    commit("john", "2017-08-01", "first commit")
    commit("bob", "2017-08-01", "second commit")

    val userActivity = aggregateBy(EMAIL_DAY)

    userActivity should have size 2
    userActivity.map(_.email) should contain allOf("john", "bob")
    forAll(userActivity) {
      _.getCount should be(1)
    }
  }

  "AggregatedHistogramFilter by email and hour" should "aggregate two commits of the same author on the same hour" in {
    commit("john", "2017-08-01 10:15:03", "first commit")
    commit("john", "2017-08-01 10:45:01", "second commit")

    val userActivity = aggregateBy(EMAIL_HOUR)

    userActivity should have size 1
    userActivity.head.email should be("john")
    userActivity.head.getCount should be(2)
  }

  it should "keep separate commits from the same author on different hours" in {
    commit("john", "2017-08-01 10:15:03", "first commit")
    commit("john", "2017-08-01 11:30:01", "second commit")

    val userActivity = aggregateBy(EMAIL_HOUR)

    userActivity should have size 2
    forAll(userActivity) {
      activity => {
        activity.email should be("john")
        activity.getCount should be(1)
      }
    }
  }

  it should "keep separate commits from different authors on the same hour" in {
    commit("john", "2017-08-01 10:15:03", "first commit")
    commit("bob", "2017-08-01 10:20:00", "second commit")

    val userActivity = aggregateBy(EMAIL_HOUR)

    userActivity should have size 2
    forAll(userActivity) {
      _.getCount should be(1)
    }
    userActivity.map(_.email) should contain allOf("john", "bob")
  }
}
