<commit_before>// @flow

import {
  type CookieSource,
  type SessionIdentifierType,
  cookieTypes,
  sessionIdentifierTypes,
} from 'lib/types/session-types';
import type { Platform, PlatformDetails } from 'lib/types/device-types';
import type { CalendarQuery } from 'lib/types/entry-types';

import invariant from 'invariant';

import { ServerError } from 'lib/utils/errors';

export type UserViewerData = {|
  +loggedIn: true,
  +id: string,
  +platformDetails: ?PlatformDetails,
  +deviceToken: ?string,
  +userID: string,
  +cookieID: ?string,
  +cookieSource?: CookieSource,
  +cookiePassword: ?string,
  +cookieInsertedThisRequest?: bool,
  +sessionIdentifierType?: SessionIdentifierType,
  +sessionID: ?string,
  +sessionInfo: ?SessionInfo,
  +isBotViewer: bool,
|};

export type AnonymousViewerData = {|
  +loggedIn: false,
  +id: string,
  +platformDetails: ?PlatformDetails,
  +deviceToken: ?string,
  +cookieSource?: CookieSource,
  +cookieID: ?string,
  +cookiePassword: ?string,
  +cookieInsertedThisRequest?: bool,
  +sessionIdentifierType?: SessionIdentifierType,
  +sessionID: ?string,
  +sessionInfo: ?SessionInfo,
  +isBotViewer: bool,
|};

type SessionInfo = {|
  lastValidated: number,
  calendarQuery: CalendarQuery,
|};

export type ViewerData = UserViewerData | AnonymousViewerData;

class Viewer {

  data: ViewerData;
  sessionChanged = false;
  cookieInvalidated = false;
  initialCookieName: string;

  constructor(data: ViewerData) {
    invariant(
      data.cookieSource !== null && data.cookieSource !== undefined,
      "data.cookieSource passed to Viewer constructor should be set",
    );
    invariant(
      data.sessionIdentifierType !== null &&
        data.sessionIdentifierType !== undefined,
      "data.sessionIdentifierType passed to Viewer constructor should be set",
    );
    this.data = data;
    this.initialCookieName = Viewer.cookieNameFromViewerData(data);
  }

  static cookieNameFromViewerData(data: ViewerData) {
    return data.loggedIn
      ? cookieTypes.USER
      : cookieTypes.ANONYMOUS;
  }

  getData() {
    return this.data;
  }

  setNewCookie(data: ViewerData) {
    if (data.cookieSource === null || data.cookieSource === undefined) {
      if (data.loggedIn) {
        data = { ...data, cookieSource: this.cookieSource };
      } else {
        // This is a separate condition because of Flow
        data = { ...data, cookieSource: this.cookieSource };
      }
    }
    if (
      data.sessionIdentifierType === null ||
      data.sessionIdentifierType === undefined
    ) {
      if (data.loggedIn) {
        data = { ...data, sessionIdentifierType: this.sessionIdentifierType };<commit_msg>[server] Allow Viewer construction without cookie info<commit_after>// @flow

import {
  type CookieSource,
  type SessionIdentifierType,
  cookieTypes,
  sessionIdentifierTypes,
} from 'lib/types/session-types';
import type { Platform, PlatformDetails } from 'lib/types/device-types';
import type { CalendarQuery } from 'lib/types/entry-types';

import invariant from 'invariant';

import { ServerError } from 'lib/utils/errors';

export type UserViewerData = {|
  +loggedIn: true,
  +id: string,
  +platformDetails: ?PlatformDetails,
  +deviceToken: ?string,
  +userID: string,
  +cookieID: ?string,
  +cookieSource?: CookieSource,
  +cookiePassword: ?string,
  +cookieInsertedThisRequest?: bool,
  +sessionIdentifierType?: SessionIdentifierType,
  +sessionID: ?string,
  +sessionInfo: ?SessionInfo,
  +isBotViewer: bool,
|};

export type AnonymousViewerData = {|
  +loggedIn: false,
  +id: string,
  +platformDetails: ?PlatformDetails,
  +deviceToken: ?string,
  +cookieSource?: CookieSource,
  +cookieID: ?string,
  +cookiePassword: ?string,
  +cookieInsertedThisRequest?: bool,
  +sessionIdentifierType?: SessionIdentifierType,
  +sessionID: ?string,
  +sessionInfo: ?SessionInfo,
  +isBotViewer: bool,
|};

type SessionInfo = {|
  lastValidated: number,
  calendarQuery: CalendarQuery,
|};

export type ViewerData = UserViewerData | AnonymousViewerData;

class Viewer {

  data: ViewerData;
  sessionChanged = false;
  cookieInvalidated = false;
  initialCookieName: string;

  constructor(data: ViewerData) {
    this.data = data;
    this.initialCookieName = Viewer.cookieNameFromViewerData(data);
  }

  static cookieNameFromViewerData(data: ViewerData) {
    return data.loggedIn
      ? cookieTypes.USER
      : cookieTypes.ANONYMOUS;
  }

  getData() {
    return this.data;
  }

  setNewCookie(data: ViewerData) {
    if (data.cookieSource === null || data.cookieSource === undefined) {
      if (data.loggedIn) {
        data = { ...data, cookieSource: this.cookieSource };
      } else {
        // This is a separate condition because of Flow
        data = { ...data, cookieSource: this.cookieSource };
      }
    }
    if (
      data.sessionIdentifierType === null ||
      data.sessionIdentifierType === undefined
    ) {
      if (data.loggedIn) {
        data = { ...data, sessionIdentifierType: this.sessionIdentifierType };
{'fraction_non_alphanumeric': 0.11811652035115722, 'fraction_numerical': 0.0, 'mean_word_length': 3.871720116618076, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 3, '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': '2334420', 'n_tokens_mistral': 1543, 'n_tokens_neox': 1513, 'n_words': 352}