// Copyright 2017 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT

package repo

import (
	"net/http"
	"time"

	activities_model "gitea.dev/models/activities"
	git_model "gitea.dev/models/git"
	"gitea.dev/models/unit"
	"gitea.dev/modules/templates"
	"gitea.dev/services/context"
)

const (
	tplActivity templates.TplName = "repo/activity"
)

// Activity render the page to show repository latest changes
func Activity(ctx *context.Context) {
	ctx.Data["Title"] = ctx.Tr("repo.activity")
	ctx.Data["PageIsActivity"] = true

	ctx.Data["PageIsPulse"] = true

	timeUntil := time.Now()
	period, timeFrom := "weekly", timeUntil.Add(-time.Hour*168)
	switch ctx.PathParam("period") {
	case "daily":
		period, timeFrom = "daily", timeUntil.Add(-time.Hour*24)
	case "halfweekly":
		period, timeFrom = "halfweekly", timeUntil.Add(-time.Hour*72)
	case "weekly":
		period, timeFrom = "weekly", timeUntil.Add(-time.Hour*168)
	case "monthly":
		period, timeFrom = "monthly", timeUntil.AddDate(0, -1, 0)
	case "quarterly":
		period, timeFrom = "quarterly", timeUntil.AddDate(0, -3, 0)
	case "semiyearly":
		period, timeFrom = "semiyearly", timeUntil.AddDate(0, -6, 0)
	case "yearly":
		period, timeFrom = "yearly", timeUntil.AddDate(-1, 0, 0)
	}
	ctx.Data["DateFrom"] = timeFrom
	ctx.Data["DateUntil"] = timeUntil
	ctx.Data["Period"] = period
	ctx.Data["PeriodText"] = ctx.Tr("repo.activity.period." + period)

	canReadCode := ctx.Repo.Permission.CanRead(unit.TypeCode)
	if canReadCode {
		// GetActivityStats needs to read the default branch to get some information
		branchExist, _ := git_model.IsBranchExist(ctx, ctx.Repo.Repository.ID, ctx.Repo.Repository.DefaultBranch)
		if !branchExist {
			ctx.Data["NotFoundPrompt"] = ctx.Tr("repo.branch.default_branch_not_exist", ctx.Repo.Repository.DefaultBranch)
			ctx.NotFound(nil)
			return
		}
	}

	var err error
	// TODO: refactor these arguments to a struct
	ctx.Data["Activity"], err = activities_model.GetActivityStats(ctx, ctx.Repo.Repository, timeFrom,
		ctx.Repo.Permission.CanRead(unit.TypeReleases),
		ctx.Repo.Permission.CanRead(unit.TypeIssues),
		ctx.Repo.Permission.CanRead(unit.TypePullRequests),
		canReadCode,
	)
	if err != nil {
		ctx.ServerError("GetActivityStats", err)
		return
	}

	if ctx.PageData["repoActivityTopAuthors"], err = activities_model.GetActivityStatsTopAuthors(ctx, ctx.Repo.Repository, timeFrom, 10); err != nil {
		ctx.ServerError("GetActivityStatsTopAuthors", err)
		return
	}

	ctx.HTML(http.StatusOK, tplActivity)
}

// ActivityAuthors renders JSON with top commit authors for given time period over all branches
func ActivityAuthors(ctx *context.Context) {
	timeUntil := time.Now()
	var timeFrom time.Time

	switch ctx.PathParam("period") {
	case "daily":
		timeFrom = timeUntil.Add(-time.Hour * 24)
	case "halfweekly":
		timeFrom = timeUntil.Add(-time.Hour * 72)
	case "weekly":
		timeFrom = timeUntil.Add(-time.Hour * 168)
	case "monthly":
		timeFrom = timeUntil.AddDate(0, -1, 0)
	case "quarterly":
		timeFrom = timeUntil.AddDate(0, -3, 0)
	case "semiyearly":
		timeFrom = timeUntil.AddDate(0, -6, 0)
	case "yearly":
		timeFrom = timeUntil.AddDate(-1, 0, 0)
	default:
		timeFrom = timeUntil.Add(-time.Hour * 168)
	}

	authors, err := activities_model.GetActivityStatsTopAuthors(ctx, ctx.Repo.Repository, timeFrom, 10)
	if err != nil {
		ctx.ServerError("GetActivityStatsTopAuthors", err)
		return
	}

	ctx.JSON(http.StatusOK, authors)
}
