<commit_before>package controllers

import play.api.libs.json.Json
import play.api.libs.json.JsValue
import play.api.mvc._
import views._

import lila.api.Context
import lila.app._
import lila.insight.{ InsightDimension, InsightMetric }

final class Insight(env: Env) extends LilaController(env) {

  def refresh(username: String) =
    OpenOrScoped()(
      open = implicit ctx =>
        Accessible(username) { user =>
          env.insight.api indexAll user inject Ok
        },
      scoped = req =>
        me =>
          AccessibleApi(username)(me.some) { user =>
            env.insight.api indexAll user inject Ok
          }
    )

  def index(username: String) = {
    def jsonStatus(user: lila.user.User) =
      env.insight.api userStatus user map { status =>
        Ok(Json.obj("status" -> status.toString))
      }
    OpenOrScoped()(
      open = implicit ctx =>
        Accessible(username) { user =>
          render.async {
            case Accepts.Html() => doPath(user, InsightMetric.MeanCpl.key, InsightDimension.Perf.key, "")
            case Accepts.Json() => jsonStatus(user)
          }
        },
      scoped = req => me => AccessibleApi(username)(me.some)(jsonStatus)
    )
  }

  def path(username: String, metric: String, dimension: String, filters: String) =
    Open { implicit ctx =>
      Accessible(username) { doPath(_, metric, dimension, ~lila.common.String.decodeUriPath(filters)) }
    }

  private def doPath(user: lila.user.User, metric: String, dimension: String, filters: String)(implicit
      ctx: Context
  ) = {
    import lila.insight.InsightApi.UserStatus._
    env.insight.api userStatus user flatMap {
      case NoGame => Ok(html.site.message.insightNoGames(user)).fuccess
      case Empty  => Ok(html.insight.empty(user)).fuccess
      case s =>
        for {
          cache  <- env.insight.api insightUser user
          prefId <- env.insight.share getPrefId user
        } yield Ok(
          html.insight.index(
            u = user,
            cache = cache,
            prefId = prefId,
            ui = env.insight.jsonView.ui(cache.families, cache.openings, asMod = isGranted(_.ViewBlurs)),
            question = env.insight.jsonView.question(metric, dimension, filters),
            stale = s == Stale
          )
        )
    }
  }

  def json(username: String) =
    OpenOrScopedBody(parse.json)(Nil)(
      open = implicit ctx => {
        AccessibleApi(username)(ctx.me) { user =>
          processQuestion(user, ctx.body)
        }
      },
      scoped = req =>
        me =>
          AccessibleApi(username)(me.some) { user =>
            processQuestion(user, req)
          }
    )

  private def processQuestion(user: lila.user.User, body: Request[JsValue]) = {
    import lila.insight.JsonQuestion, JsonQuestion._
    implicit val lang = reqLang(body)
    body.body
      .validate[JsonQuestion]
      .fold(
        err => BadRequest(jsonError(err.toString)).fuccess,
        _.question.fold(BadRequest.fuccess) { q =>
          env.insight.api.ask(q, user) map
            lila.insight.Chart.fromAnswer(env.user.lightUserSync) map
            env.insight.jsonView.chart.apply map { Ok(_) }
        }
      )
  }

  private def Accessible(username: String)(f: lila.user.User => Fu[Result])(implicit ctx: Context) =
    env.user.repo named username flatMap {
      _.fold(notFound) { u =>
        env.insight.share.grant(u, ctx.me) flatMap {
          case true => f(u)
          case _    => fuccess(Forbidden(html.insight.forbidden(u)))
        }
      }
    }

  private def AccessibleApi(username: String)(me: Option[lila.user.User])(f: lila.user.User => Fu[Result]) =
    env.user.repo named username flatMap {
      _ ?? { u =>
        env.insight.share.grant(u, me) flatMap {
          case true => f(u)
          case _    => fuccess(Forbidden)
        }
      }
    }<commit_msg>fix insight lang - closes #11393<commit_after>package controllers

import play.api.libs.json.Json
import play.api.libs.json.JsValue
import play.api.mvc._
import views._

import lila.api.Context
import lila.app._
import lila.insight.{ InsightDimension, InsightMetric }

final class Insight(env: Env) extends LilaController(env) {

  def refresh(username: String) =
    OpenOrScoped()(
      open = implicit ctx =>
        Accessible(username) { user =>
          env.insight.api indexAll user inject Ok
        },
      scoped = req =>
        me =>
          AccessibleApi(username)(me.some) { user =>
            env.insight.api indexAll user inject Ok
          }
    )

  def index(username: String) = {
    def jsonStatus(user: lila.user.User) =
      env.insight.api userStatus user map { status =>
        Ok(Json.obj("status" -> status.toString))
      }
    OpenOrScoped()(
      open = implicit ctx =>
        Accessible(username) { user =>
          render.async {
            case Accepts.Html() => doPath(user, InsightMetric.MeanCpl.key, InsightDimension.Perf.key, "")
            case Accepts.Json() => jsonStatus(user)
          }
        },
      scoped = req => me => AccessibleApi(username)(me.some)(jsonStatus)
    )
  }

  def path(username: String, metric: String, dimension: String, filters: String) =
    Open { implicit ctx =>
      Accessible(username) { doPath(_, metric, dimension, ~lila.common.String.decodeUriPath(filters)) }
    }

  private def doPath(user: lila.user.User, metric: String, dimension: String, filters: String)(implicit
      ctx: Context
  ) = {
    import lila.insight.InsightApi.UserStatus._
    env.insight.api userStatus user flatMap {
      case NoGame => Ok(html.site.message.insightNoGames(user)).fuccess
      case Empty  => Ok(html.insight.empty(user)).fuccess
      case s =>
        for {
          cache  <- env.insight.api insightUser user
          prefId <- env.insight.share getPrefId user
        } yield Ok(
          html.insight.index(
            u = user,
            cache = cache,
            prefId = prefId,
            ui = env.insight.jsonView.ui(cache.families, cache.openings, asMod = isGranted(_.ViewBlurs)),
            question = env.insight.jsonView.question(metric, dimension, filters),
            stale = s == Stale
          )
        )
    }
  }

  def json(username: String) =
    OpenOrScopedBody(parse.json)(Nil)(
      open = implicit ctx => {
        AccessibleApi(username)(ctx.me) { user =>
          processQuestion(user, ctx.body)
        }
      },
      scoped = req =>
        me =>
          AccessibleApi(username)(me.some) { user =>
            processQuestion(user, req)
          }
    )

  private def processQuestion(user: lila.user.User, body: Request[JsValue])(implicit lang: Lang) = {
    import lila.insight.JsonQuestion, JsonQuestion._
    body.body
      .validate[JsonQuestion]
      .fold(
        err => BadRequest(jsonError(err.toString)).fuccess,
        _.question.fold(BadRequest.fuccess) { q =>
          env.insight.api.ask(q, user) map
            lila.insight.Chart.fromAnswer(env.user.lightUserSync) map
            env.insight.jsonView.chart.apply map { Ok(_) }
        }
      )
  }

  private def Accessible(username: String)(f: lila.user.User => Fu[Result])(implicit ctx: Context) =
    env.user.repo named username flatMap {
      _.fold(notFound) { u =>
        env.insight.share.grant(u, ctx.me) flatMap {
          case true => f(u)
          case _    => fuccess(Forbidden(html.insight.forbidden(u)))
        }
      }
    }

  private def AccessibleApi(username: String)(me: Option[lila.user.User])(f: lila.user.User => Fu[Result]) =
    env.user.repo named username flatMap {
      _ ?? { u =>
        env.insight.share.grant(u, me) flatMap {
          case true => f(u)
          case _    => fuccess(Forbidden)
        }
      }
    }
{'fraction_non_alphanumeric': 0.12383660806618407, 'fraction_numerical': 0.0006463288521199586, 'mean_word_length': 2.248110831234257, 'pattern_counts': {'":': 0, '<': 7, '<?xml version=': 0, '>': 67, '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': '6788455', 'n_tokens_mistral': 2422, 'n_tokens_neox': 2387, 'n_words': 484}