<commit_before>package controllers

import play.api.data.Form
import play.api.data.Forms._
import play.api.libs.json._
import play.api.mvc._
import scala.concurrent.duration._

import lila.api.Context
import lila.app._
import lila.common.config.MaxPerSecond
import lila.hub.LightTeam
import lila.security.Granter
import lila.team.{ Joined, Motivate, Team => TeamModel }
import lila.user.{ User => UserModel }
import views._

final class Team(
    env: Env,
    apiC: => Api
) extends LilaController(env) {

  private def forms     = env.team.forms
  private def api       = env.team.api
  private def paginator = env.team.paginator

  def all(page: Int) =
    Open { implicit ctx =>
      paginator popularTeams page map {
        html.team.list.all(_)
      }
    }

  def home(page: Int) =
    Open { implicit ctx =>
      ctx.me.??(api.hasTeams) map {
        case true  => Redirect(routes.Team.mine())
        case false => Redirect(routes.Team.all(page))
      }
    }

  def show(id: String, page: Int) =
    Open { implicit ctx =>
      OptionFuOk(api team id) { renderTeam(_, page) }
    }

  def search(text: String, page: Int) =
    OpenBody { implicit ctx =>
      if (text.trim.isEmpty) paginator popularTeams page map { html.team.list.all(_) }
      else
        env.teamSearch(text, page) map { html.team.list.search(text, _) }
    }

  private def renderTeam(team: TeamModel, page: Int = 1)(implicit ctx: Context) =
    for {
      info    <- env.teamInfo(team, ctx.me)
      members <- paginator.teamMembers(team, page)
      hasChat = canHaveChat(team, info)
      chat <-
        hasChat ?? env.chat.api.userChat.cached
          .findMine(lila.chat.Chat.Id(team.id), ctx.me)
          .map(some)
      _ <- env.user.lightUserApi preloadMany {
        info.userIds ::: chat.??(_.chat.userIds)
      }
      version <- hasChat ?? env.team.version(team.id).dmap(some)
    } yield html.team.show(team, members, info, chat, version)

  private def canHaveChat(team: TeamModel, info: lila.app.mashup.TeamInfo)(implicit ctx: Context): Boolean =
    !team.isChatFor(_.NONE) && ctx.noKid && {
      (team.isChatFor(_.LEADERS) && ctx.userId.exists(team.leaders)) ||
      (team.isChatFor(_.MEMBERS) && info.mine) ||
      isGranted(_.ChatTimeout)
    }

  def legacyUsers(teamId: String) =
    Action {
      MovedPermanently(routes.Team.users(teamId).url)
    }

  def users(teamId: String) =
    Action.async { implicit req =>
      api.team(teamId) flatMap {
        _ ?? { team =>
          apiC.jsonStream {
            env.team
              .memberStream(team, MaxPerSecond(20))
              .map(env.api.userApi.one)
          }.fuccess
        }
      }
    }

  def tournaments(teamId: String) =
    Open { implicit ctx =>
      env.team.teamRepo.enabled(teamId) flatMap {
        _ ?? { team =>
          env.teamInfo.tournaments(team, 30, 30) map { tours =>
            Ok(html.team.tournaments.page(team, tours))
          }
        }
      }
    }

  def edit(id: String) =
    Auth { implicit ctx => _ =>
      WithOwnedTeam(id) { team =>
        fuccess(html.team.form.edit(team, forms edit team))
      }
    }

  def update(id: String) =
    AuthBody { implicit ctx => me =>
      WithOwnedTeam(id) { team =>
        implicit val req = ctx.body
        forms
          .edit(team)
          .bindFromRequest()
          .fold(
            err => BadRequest(html.team.form.edit(team, err)).fuccess,
            data => api.update(team, data, me) inject Redirect(routes.Team.show(team.id)).flashSuccess
          )
      }
    }

  def kickForm(id: String) =
    Auth { implicit ctx => me =>
      WithOwnedTeam(id) { team =>
        env.team.memberRepo userIdsByTeam team.id map { userIds =>
          html.team.admin.kick(team, userIds - me.id)
        }
      }
    }

  def kick(id: String) =
    AuthBody { implicit ctx => me =>
      WithOwnedTeam(id) { team =>
        implicit val req = ctx.body
        forms.selectMember.bindFromRequest().value ?? { api.kick(team, _, me) } inject Redirect(
          routes.Team.show(team.id)
        ).flashSuccess
      }
    }
  def kickUser(teamId: String, userId: String) =
    Scoped(_.Team.Write) { _ => me =>
      api team teamId flatMap {
        _ ?? { team =>
          if (team leaders me.id) api.kick(team, userId, me) inject jsonOkResult
          else Forbidden(jsonError("Not your team")).fuccess
        }
      }
    }

  def leadersForm(id: String) =
    Auth { implicit ctx => _ =>
      WithOwnedTeam(id) { team =>
        Ok(html.team.admin.leaders(team, forms leaders team)).fuccess
      }
    }

  def leaders(id: String) =
    AuthBody { implicit ctx => me =>
      WithOwnedTeam(id) { team =>
        implicit val req = ctx.body
        forms.leaders(team).bindFromRequest().value ?? { api.setLeaders(team, _, me, isGranted(_.ManageTeam)) } inject Redirect(
          routes.Team.show(team.id)
        ).flashSuccess
      }
    }

  def close(id: String) =
    Secure(_.ManageTeam) { implicit ctx => me =>
      OptionFuResult(api team id) { team =>
        (api delete team) >>
          env.mod.logApi.deleteTeam(me.id, team.name, team.description) inject
          Redirect(routes.Team all 1).flashSuccess
      }
    }

  def disable(id: String) =
    Auth { implicit ctx => me =>
      WithOwnedTeam(id) { team =>
        (api disable team) >>
          env.mod.logApi.disableTeam(me.id, team.name, team.description) inject<commit_msg>code format<commit_after>package controllers

import scala.concurrent.duration._

import play.api.data.Form
import play.api.data.Forms._
import play.api.libs.json._
import play.api.mvc._
import views._

import lila.api.Context
import lila.app._
import lila.common.config.MaxPerSecond
import lila.hub.LightTeam
import lila.security.Granter
import lila.team.{ Joined, Motivate, Team => TeamModel }
import lila.user.{ User => UserModel }

final class Team(
    env: Env,
    apiC: => Api
) extends LilaController(env) {

  private def forms     = env.team.forms
  private def api       = env.team.api
  private def paginator = env.team.paginator

  def all(page: Int) =
    Open { implicit ctx =>
      paginator popularTeams page map {
        html.team.list.all(_)
      }
    }

  def home(page: Int) =
    Open { implicit ctx =>
      ctx.me.??(api.hasTeams) map {
        case true  => Redirect(routes.Team.mine())
        case false => Redirect(routes.Team.all(page))
      }
    }

  def show(id: String, page: Int) =
    Open { implicit ctx =>
      OptionFuOk(api team id) { renderTeam(_, page) }
    }

  def search(text: String, page: Int) =
    OpenBody { implicit ctx =>
      if (text.trim.isEmpty) paginator popularTeams page map { html.team.list.all(_) }
      else
        env.teamSearch(text, page) map { html.team.list.search(text, _) }
    }

  private def renderTeam(team: TeamModel, page: Int = 1)(implicit ctx: Context) =
    for {
      info    <- env.teamInfo(team, ctx.me)
      members <- paginator.teamMembers(team, page)
      hasChat = canHaveChat(team, info)
      chat <-
        hasChat ?? env.chat.api.userChat.cached
          .findMine(lila.chat.Chat.Id(team.id), ctx.me)
          .map(some)
      _ <- env.user.lightUserApi preloadMany {
        info.userIds ::: chat.??(_.chat.userIds)
      }
      version <- hasChat ?? env.team.version(team.id).dmap(some)
    } yield html.team.show(team, members, info, chat, version)

  private def canHaveChat(team: TeamModel, info: lila.app.mashup.TeamInfo)(implicit ctx: Context): Boolean =
    !team.isChatFor(_.NONE) && ctx.noKid && {
      (team.isChatFor(_.LEADERS) && ctx.userId.exists(team.leaders)) ||
      (team.isChatFor(_.MEMBERS) && info.mine) ||
      isGranted(_.ChatTimeout)
    }

  def legacyUsers(teamId: String) =
    Action {
      MovedPermanently(routes.Team.users(teamId).url)
    }

  def users(teamId: String) =
    Action.async { implicit req =>
      api.team(teamId) flatMap {
        _ ?? { team =>
          apiC.jsonStream {
            env.team
              .memberStream(team, MaxPerSecond(20))
              .map(env.api.userApi.one)
          }.fuccess
        }
      }
    }

  def tournaments(teamId: String) =
    Open { implicit ctx =>
      env.team.teamRepo.enabled(teamId) flatMap {
        _ ?? { team =>
          env.teamInfo.tournaments(team, 30, 30) map { tours =>
            Ok(html.team.tournaments.page(team, tours))
          }
        }
      }
    }

  def edit(id: String) =
    Auth { implicit ctx => _ =>
      WithOwnedTeam(id) { team =>
        fuccess(html.team.form.edit(team, forms edit team))
      }
    }

  def update(id: String) =
    AuthBody { implicit ctx => me =>
      WithOwnedTeam(id) { team =>
        implicit val req = ctx.body
        forms
          .edit(team)
          .bindFromRequest()
          .fold(
            err => BadRequest(html.team.form.edit(team, err)).fuccess,
            data => api.update(team, data, me) inject Redirect(routes.Team.show(team.id)).flashSuccess
          )
      }
    }

  def kickForm(id: String) =
    Auth { implicit ctx => me =>
      WithOwnedTeam(id) { team =>
        env.team.memberRepo userIdsByTeam team.id map { userIds =>
          html.team.admin.kick(team, userIds - me.id)
        }
      }
    }

  def kick(id: String) =
    AuthBody { implicit ctx => me =>
      WithOwnedTeam(id) { team =>
        implicit val req = ctx.body
        forms.selectMember.bindFromRequest().value ?? { api.kick(team, _, me) } inject Redirect(
          routes.Team.show(team.id)
        ).flashSuccess
      }
    }
  def kickUser(teamId: String, userId: String) =
    Scoped(_.Team.Write) { _ => me =>
      api team teamId flatMap {
        _ ?? { team =>
          if (team leaders me.id) api.kick(team, userId, me) inject jsonOkResult
          else Forbidden(jsonError("Not your team")).fuccess
        }
      }
    }

  def leadersForm(id: String) =
    Auth { implicit ctx => _ =>
      WithOwnedTeam(id) { team =>
        Ok(html.team.admin.leaders(team, forms leaders team)).fuccess
      }
    }

  def leaders(id: String) =
    AuthBody { implicit ctx => me =>
      WithOwnedTeam(id) { team =>
        implicit val req = ctx.body
        forms.leaders(team).bindFromRequest().value ?? {
          api.setLeaders(team, _, me, isGranted(_.ManageTeam))
        } inject Redirect(
          routes.Team.show(team.id)
        ).flashSuccess
      }
    }

  def close(id: String) =
    Secure(_.ManageTeam) { implicit ctx => me =>
      OptionFuResult(api team id) { team =>
        (api delete team) >>
          env.mod.logApi.deleteTeam(me.id, team.name, team.description) inject
          Redirect(routes.Team all 1).flashSuccess
      }
    }

  def disable(id: String) =
    Auth { implicit ctx => me =>
      WithOwnedTeam(id) { team =>
        (api disable team) >>
          env.mod.logApi.disableTeam(me.id, team.name, team.description) inject
{'fraction_non_alphanumeric': 0.13180357962368058, 'fraction_numerical': 0.001468563561266636, 'mean_word_length': 2.2284444444444444, 'pattern_counts': {'":': 0, '<': 13, '<?xml version=': 0, '>': 99, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3070208', 'n_tokens_mistral': 3593, 'n_tokens_neox': 3540, 'n_words': 746}