<commit_before>/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

import Foundation
import Shared
import XCGLogger

private let log = Logger.syncLogger

let ONE_YEAR_IN_SECONDS = 365 * 24 * 60 * 60

/**
 * Immutable representation for Sync records.
 *
 * Envelopes consist of:
 *   Required: "id", "collection", "payload".
 *   Optional: "modified", "sortindex", "ttl".
 *
 * Deletedness is a property of the payload.
 */
open class Record<T: CleartextPayloadJSON> {
    open let id: String
    open let payload: T

    open let modified: Timestamp
    open let sortindex: Int
    open let ttl: Int?              // Seconds. Can be null, which means 'don't expire'.

    // This is a hook for decryption.
    // Right now it only parses the string. In subclasses, it'll parse the
    // string, decrypt the contents, and return the data as a JSON object.
    // From the docs:
    //
    //   payload  none  string 256k
    //   A string containing a JSON structure encapsulating the data of the record.
    //   This structure is defined separately for each WBO type.
    //   Parts of the structure may be encrypted, in which case the structure
    //   should also specify a record for decryption.
    //
    // @seealso EncryptedRecord.
    open class func payloadFromPayloadString(_ envelope: EnvelopeJSON, payload: String) -> T? {
        return T(payload)
    }

    // TODO: consider using error tuples.
    open class func fromEnvelope(_ envelope: EnvelopeJSON, payloadFactory: (String) -> T?) -> Record<T>? {
        if !(envelope.isValid()) {
            log.error("Invalid envelope.")
            return nil
        }
        print("the payload is \(envelope.payload)")
        guard let payload = payloadFactory(envelope.payload) else {
            log.error("Unable to parse payload.")
            return nil
        }

        if !payload.isValid() {
            log.error("Invalid payload \(envelope.payload).")
            return nil
        }

        return Record<T>(envelope: envelope, payload: payload)
    }

    /**
     * Accepts an envelope and a decrypted payload.
     * Inputs are not validated. Use `fromEnvelope` above.
     */<commit_msg>No bug - remove excessive logging when downloading records. r=sleroux (#2764)<commit_after>/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

import Foundation
import Shared
import XCGLogger

private let log = Logger.syncLogger

let ONE_YEAR_IN_SECONDS = 365 * 24 * 60 * 60

/**
 * Immutable representation for Sync records.
 *
 * Envelopes consist of:
 *   Required: "id", "collection", "payload".
 *   Optional: "modified", "sortindex", "ttl".
 *
 * Deletedness is a property of the payload.
 */
open class Record<T: CleartextPayloadJSON> {
    open let id: String
    open let payload: T

    open let modified: Timestamp
    open let sortindex: Int
    open let ttl: Int?              // Seconds. Can be null, which means 'don't expire'.

    // This is a hook for decryption.
    // Right now it only parses the string. In subclasses, it'll parse the
    // string, decrypt the contents, and return the data as a JSON object.
    // From the docs:
    //
    //   payload  none  string 256k
    //   A string containing a JSON structure encapsulating the data of the record.
    //   This structure is defined separately for each WBO type.
    //   Parts of the structure may be encrypted, in which case the structure
    //   should also specify a record for decryption.
    //
    // @seealso EncryptedRecord.
    open class func payloadFromPayloadString(_ envelope: EnvelopeJSON, payload: String) -> T? {
        return T(payload)
    }

    // TODO: consider using error tuples.
    open class func fromEnvelope(_ envelope: EnvelopeJSON, payloadFactory: (String) -> T?) -> Record<T>? {
        if !(envelope.isValid()) {
            log.error("Invalid envelope.")
            return nil
        }
        guard let payload = payloadFactory(envelope.payload) else {
            log.error("Unable to parse payload.")
            return nil
        }

        if !payload.isValid() {
            log.error("Invalid payload \(envelope.payload).")
            return nil
        }

        return Record<T>(envelope: envelope, payload: payload)
    }

    /**
     * Accepts an envelope and a decrypted payload.
     * Inputs are not validated. Use `fromEnvelope` above.
     */
{'fraction_non_alphanumeric': 0.09480909480909482, 'fraction_numerical': 0.007722007722007722, 'mean_word_length': 2.401167031363968, 'pattern_counts': {'":': 0, '<': 9, '<?xml version=': 0, '>': 15, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 1, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3989742', 'n_tokens_mistral': 1327, 'n_tokens_neox': 1273, 'n_words': 521}