import type { RelativeTime, ContextValue, Context, CustomerDataTracker } from '@datadog/browser-core'
import { SESSION_TIME_OUT_DELAY, createValueHistory } from '@datadog/browser-core'
import type { LifeCycle } from '../lifeCycle'
import { LifeCycleEventType } from '../lifeCycle'

export const FEATURE_FLAG_CONTEXT_TIME_OUT_DELAY = SESSION_TIME_OUT_DELAY
export const BYTES_COMPUTATION_THROTTLING_DELAY = 200

export type FeatureFlagContext = Context

export interface FeatureFlagContexts {
  findFeatureFlagEvaluations: (startTime?: RelativeTime) => FeatureFlagContext | undefined
  addFeatureFlagEvaluation: (key: string, value: ContextValue) => void
  stop: () => void
}

/**
 * Start feature flag contexts
 *
 * Feature flag contexts follow the life of views.
 * A new context is added when a view is created and ended when the view is ended
 *
 * Note: we choose not to add a new context at each evaluation to save memory
 */
export function startFeatureFlagContexts(
  lifeCycle: LifeCycle,
  customerDataTracker: CustomerDataTracker
): FeatureFlagContexts {
  const featureFlagContexts = createValueHistory<FeatureFlagContext>({
    expireDelay: FEATURE_FLAG_CONTEXT_TIME_OUT_DELAY,
  })

  lifeCycle.subscribe(LifeCycleEventType.BEFORE_VIEW_CREATED, ({ startClocks }) => {
    featureFlagContexts.add({}, startClocks.relative)
    customerDataTracker.resetCustomerData()
  })

  lifeCycle.subscribe(LifeCycleEventType.AFTER_VIEW_ENDED, ({ endClocks }) => {
    featureFlagContexts.closeActive(endClocks.relative)
  })

  return {
    findFeatureFlagEvaluations: (startTime?: RelativeTime) => featureFlagContexts.find(startTime),
    addFeatureFlagEvaluation: (key: string, value: ContextValue) => {
      const currentContext = featureFlagContexts.find()
      if (currentContext) {
        currentContext[key] = value
        customerDataTracker.updateCustomerData(currentContext)
      }
    },
    stop: () => customerDataTracker.stop(),
  }
}
