// Copyright 2015 - Present, The Gogs Authors. All rights reserved.
// Copyright 2018 - Present, Gitote. All rights reserved.
//
// This source code is licensed under the MIT license found in the
// LICENSE file in the root directory of this source tree.

package user

import (
	"gitote/gitote/models"
	"gitote/gitote/pkg/context"

	api "gitlab.com/gitote/go-gitote-client"
)

func responseAPIUsers(c *context.APIContext, users []*models.User) {
	apiUsers := make([]*api.User, len(users))
	for i := range users {
		apiUsers[i] = users[i].APIFormat()
	}
	c.JSON(200, &apiUsers)
}

func listUserFollowers(c *context.APIContext, u *models.User) {
	users, err := u.GetFollowers(c.QueryInt("page"))
	if err != nil {
		c.Error(500, "GetUserFollowers", err)
		return
	}
	responseAPIUsers(c, users)
}

// ListMyFollowers list the authenticated user's followers
func ListMyFollowers(c *context.APIContext) {
	listUserFollowers(c, c.User)
}

// ListFollowers list the given user's followers
func ListFollowers(c *context.APIContext) {
	u := GetUserByParams(c)
	if c.Written() {
		return
	}
	listUserFollowers(c, u)
}

func listUserFollowing(c *context.APIContext, u *models.User) {
	users, err := u.GetFollowing(c.QueryInt("page"))
	if err != nil {
		c.Error(500, "GetFollowing", err)
		return
	}
	responseAPIUsers(c, users)
}

// ListMyFollowing list the users that the authenticated user is following
func ListMyFollowing(c *context.APIContext) {
	listUserFollowing(c, c.User)
}

// ListFollowing list the users that the given user is following
func ListFollowing(c *context.APIContext) {
	u := GetUserByParams(c)
	if c.Written() {
		return
	}
	listUserFollowing(c, u)
}

func checkUserFollowing(c *context.APIContext, u *models.User, followID int64) {
	if u.IsFollowing(followID) {
		c.Status(204)
	} else {
		c.Status(404)
	}
}

// CheckMyFollowing whether the given user is followed by the authenticated user
func CheckMyFollowing(c *context.APIContext) {
	target := GetUserByParams(c)
	if c.Written() {
		return
	}
	checkUserFollowing(c, c.User, target.ID)
}

// CheckFollowing check if one user is following another user
func CheckFollowing(c *context.APIContext) {
	u := GetUserByParams(c)
	if c.Written() {
		return
	}
	target := GetUserByParamsName(c, ":target")
	if c.Written() {
		return
	}
	checkUserFollowing(c, u, target.ID)
}

// Follow follow a user
func Follow(c *context.APIContext) {
	target := GetUserByParams(c)
	if c.Written() {
		return
	}
	if err := models.FollowUser(c.User.ID, target.ID); err != nil {
		c.Error(500, "FollowUser", err)
		return
	}
	c.Status(204)
}

// Unfollow unfollow a user
func Unfollow(c *context.APIContext) {
	target := GetUserByParams(c)
	if c.Written() {
		return
	}
	if err := models.UnfollowUser(c.User.ID, target.ID); err != nil {
		c.Error(500, "UnfollowUser", err)
		return
	}
	c.Status(204)
}
