def apply()

in visibilitylib/src/main/scala/com/twitter/visibility/interfaces/tweets/TweetVisibilityLibrary.scala [46:267]


  def apply(
    visibilityLibrary: VisibilityLibrary,
    userSource: UserSource,
    userRelationshipSource: UserRelationshipSource,
    keywordMatcher: KeywordMatcher.Matcher,
    invitedToConversationRepo: InvitedToConversationRepo,
    decider: Decider,
    stratoClient: StratoClient,
    localizationSource: LocalizationSource,
    tweetPerspectiveSource: TweetPerspectiveSource,
    tweetMediaMetadataSource: TweetMediaMetadataSource,
    tombstoneGenerator: TombstoneGenerator,
    interstitialGenerator: LocalizedInterstitialGenerator,
    limitedActionsFeatureSwitches: FeatureSwitches,
    enableParityTest: Gate[Unit] = Gate.False
  ): Type = {
    val libraryStatsReceiver = visibilityLibrary.statsReceiver
    val stratoClientStatsReceiver = visibilityLibrary.statsReceiver.scope("strato")
    val vfEngineCounter = libraryStatsReceiver.counter("vf_engine_requests")
    val vfLatencyOverallStat = libraryStatsReceiver.stat("vf_latency_overall")
    val vfLatencyStitchBuildStat = libraryStatsReceiver.stat("vf_latency_stitch_build")
    val vfLatencyStitchRunStat = libraryStatsReceiver.stat("vf_latency_stitch_run")
    val visibilityDeciderGates = VisibilityDeciderGates(decider)
    val verdictLogger =
      createVerdictLogger(
        visibilityDeciderGates.enableVerdictLoggerTVL,
        decider,
        libraryStatsReceiver)

    val tweetLabelMaps = new StratoTweetLabelMaps(
      SafetyLabelMapSource.fromStrato(stratoClient, stratoClientStatsReceiver))

    val mediaLabelMaps = new StratoMediaLabelMaps(
      MediaSafetyLabelMapSource.fromStrato(stratoClient, stratoClientStatsReceiver))

    val tweetFeatures = new TweetFeatures(tweetLabelMaps, libraryStatsReceiver)
    val tweetPerspectiveFeatures =
      new TweetPerspectiveFeatures(tweetPerspectiveSource, libraryStatsReceiver)
    val mediaFeatures = new MediaFeatures(mediaLabelMaps, libraryStatsReceiver)
    val tweetMediaMetadataFeatures =
      new TweetMediaMetadataFeatures(tweetMediaMetadataSource, libraryStatsReceiver)
    val authorFeatures = new AuthorFeatures(userSource, libraryStatsReceiver)
    val viewerFeatures = new ViewerFeatures(userSource, libraryStatsReceiver)
    val mutedKeywordFeatures =
      new MutedKeywordFeatures(
        userSource,
        userRelationshipSource,
        keywordMatcher,
        libraryStatsReceiver,
        visibilityDeciderGates.enableFollowCheckInMutedKeyword
      )
    val relationshipFeatures =
      new RelationshipFeatures(userRelationshipSource, libraryStatsReceiver)
    val fonsrRelationshipFeatures =
      new FosnrRelationshipFeatures(
        tweetLabels = tweetLabelMaps,
        userRelationshipSource = userRelationshipSource,
        statsReceiver = libraryStatsReceiver)
    val conversationControlFeatures =
      new ConversationControlFeatures(
        relationshipFeatures,
        invitedToConversationRepo,
        libraryStatsReceiver
      )
    val exclusiveTweetFeatures =
      new ExclusiveTweetFeatures(userRelationshipSource, libraryStatsReceiver)

    val viewerSearchSafetyFeatures = new ViewerSearchSafetyFeatures(
      UserSearchSafetySource.fromStrato(stratoClient, stratoClientStatsReceiver),
      libraryStatsReceiver)

    val viewerSensitiveMediaSettingsFeatures = new ViewerSensitiveMediaSettingsFeatures(
      UserSensitiveMediaSettingsSource.fromStrato(stratoClient, stratoClientStatsReceiver),
      libraryStatsReceiver)

    val toxicReplyFilterFeature = new ToxicReplyFilterFeature(statsReceiver = libraryStatsReceiver)

    val misinfoPolicySource =
      MisinformationPolicySource.fromStrato(stratoClient, stratoClientStatsReceiver)
    val misinfoPolicyFeatures =
      new MisinformationPolicyFeatures(misinfoPolicySource, stratoClientStatsReceiver)

    val communityTweetFeatures = new CommunityTweetFeaturesV2(
      communitiesSource = CommunitiesSource.fromStrato(
        stratoClient,
        stratoClientStatsReceiver
      )
    )

    val trustedFriendsTweetFeatures = new TrustedFriendsFeatures(
      trustedFriendsSource =
        TrustedFriendsSource.fromStrato(stratoClient, stratoClientStatsReceiver))

    val editTweetFeatures = new EditTweetFeatures(libraryStatsReceiver)

    val parityTest = new TweetVisibilityLibraryParityTest(libraryStatsReceiver, stratoClient)

    val localizedNudgeSource =
      LocalizedNudgeSource.fromLocalizationSource(localizationSource)
    val tweetVisibilityNudgeFeatures =
      new TweetVisibilityNudgeSourceWrapper(localizedNudgeSource)

    val localizedLimitedActionsSource =
      LocalizedLimitedActionsSource.fromLocalizationSource(localizationSource)

    { r: TweetVisibilityRequest =>
      val elapsed = Stopwatch.start()
      var runStitchStartMs = 0L
      vfEngineCounter.incr()

      val contentId = TweetId(r.tweet.id)
      val viewerId = r.viewerContext.userId
      val authorId = coreData.userId
      val tweetGenericMediaKeys = r.tweet.mediaRefs
        .getOrElse(Seq.empty)
        .flatMap { mediaRef =>
          GenericMediaKey.fromStringKey(mediaRef.genericMediaKey)
        }

      val tpf =
        tweetPerspectiveFeatures.forTweet(
          r.tweet,
          viewerId,
          visibilityDeciderGates.enableFetchTweetReportedPerspective())

      val featureMap =
        visibilityLibrary.featureMapBuilder(
          Seq(
            mutedKeywordFeatures.forTweet(r.tweet, viewerId, authorId),
            viewerFeatures.forViewerContext(r.viewerContext),
            viewerSearchSafetyFeatures.forViewerId(viewerId),
            viewerSensitiveMediaSettingsFeatures.forViewerId(viewerId),
            relationshipFeatures.forAuthorId(authorId, viewerId),
            fonsrRelationshipFeatures
              .forTweetAndAuthorId(tweet = r.tweet, authorId = authorId, viewerId = viewerId),
            tweetFeatures.forTweet(r.tweet),
            tpf,
            mediaFeatures.forMediaKeys(tweetGenericMediaKeys),
            authorFeatures.forAuthorId(authorId),
            conversationControlFeatures.forTweet(r.tweet, viewerId),
            _.withConstantFeature(TweetIsInnerQuotedTweet, r.isInnerQuotedTweet),
            _.withConstantFeature(TweetIsRetweet, r.isRetweet),
            _.withConstantFeature(TweetIsSourceTweet, r.isSourceTweet),
            misinfoPolicyFeatures.forTweet(r.tweet, r.viewerContext),
            exclusiveTweetFeatures.forTweet(r.tweet, r.viewerContext),
            communityTweetFeatures.forTweet(r.tweet, r.viewerContext),
            tweetMediaMetadataFeatures
              .forTweet(
                r.tweet,
                tweetGenericMediaKeys,
                visibilityDeciderGates.enableFetchTweetMediaMetadata()),
            trustedFriendsTweetFeatures.forTweet(r.tweet, viewerId),
            editTweetFeatures.forTweet(r.tweet),
            toxicReplyFilterFeature.forTweet(r.tweet, viewerId),
          )
        )

      val languageCode = r.viewerContext.requestLanguageCode.getOrElse("en")
      val countryCode = r.viewerContext.requestCountryCode

      val response = visibilityLibrary
        .runRuleEngine(
          contentId,
          featureMap,
          r.viewerContext,
          r.safetyLevel
        )
        .map(
          TweetVisibilityNudgeEnrichment(
            _,
            tweetVisibilityNudgeFeatures,
            languageCode,
            countryCode))
        .map(verdict => {
          if (visibilityDeciderGates.enableBackendLimitedActions()) {
            LimitedActionsPolicyEnrichment(
              verdict,
              localizedLimitedActionsSource,
              languageCode,
              countryCode,
              limitedActionsFeatureSwitches,
              libraryStatsReceiver)
          } else {
            verdict
          }
        })
        .map(
          handleComposableVisibilityResult(
            _,
            visibilityDeciderGates.enableMediaInterstitialComposition(),
            visibilityDeciderGates.enableBackendLimitedActions()))
        .map(handleInnerQuotedTweetVisibilityResult(_, r.isInnerQuotedTweet))
        .map(tombstoneGenerator(_, languageCode))
        .map(interstitialGenerator(_, languageCode))
        .map(ComplianceTweetNoticeEnrichment(_, libraryStatsReceiver))
        .onSuccess(_ => {
          val overallStatMs = elapsed().inMilliseconds
          vfLatencyOverallStat.add(overallStatMs)
          val runStitchEndMs = elapsed().inMilliseconds
          vfLatencyStitchRunStat.add(runStitchEndMs - runStitchStartMs)
        })
        .onSuccess(
          scribeVisibilityVerdict(
            _,
            visibilityDeciderGates.enableVerdictScribingTVL,
            verdictLogger,
            r.viewerContext.userId,
            r.safetyLevel))

      runStitchStartMs = elapsed().inMilliseconds
      val buildStitchStatMs = elapsed().inMilliseconds
      vfLatencyStitchBuildStat.add(buildStitchStatMs)

      if (enableParityTest()) {
        response.applyEffect { resp =>
          Stitch.async(parityTest.runParityTest(r, resp))
        }
      } else {
        response
      }
    }
  }