<commit_before>module Logs
  class Create < Mutations::Command
    BLACKLIST = /WPA|PSK|PASSWORD|NERVES/
    BAD_WORDS = "Log message contained blacklisted words"

    required do
      # TODO: Some strange stuff happened with caching in the log service.
      #       Had to change this from "model" to "duck" as a result.
      #       See Device#refresh_cache(). Rails thinks cached `Device` objects
      #       are unsaved.
      duck  :device, methods: [:id, :is_device]
      string :message
    end

    optional do
      array :channels,
            class: String,
            in: CeleryScriptSettingsBag::ALLOWED_CHANNEL_NAMES
      # LEGACY SHIM AHEAD!!! ===================================================
      #
      # We once stored certain fields in a `meta` column.
      # The API has evolved since that time, the requirements are pretty solid
      # at this point and we need the ability to perform SQL queries. The `meta`
      # field is no longer useful nor is it a clean solution.
      #
      # Legacy FBOS versions expect logs to be in the same shape as before
      # and they also produce logs with the expectation that logs have a `meta`
      # field.
      #
      # We will keep the `meta` field around for now, but ideally, API users
      # should access `log.FOO` instead of `log.meta.FOO` for future
      # compatibility.
      #
      # TODO: delete the `meta` field once FBOS < v6.4.0 reach EOL.
      string  :type, in: Log::TYPES
      integer :x
      integer :y
      integer :z
      integer :verbosity
      integer :major_version
      integer :minor_version

      hash :meta do # This can be transitioned out soon.
        string :type, in: Log::TYPES
        optional do
          integer :x
          integer :y
          integer :z
          integer :verbosity
          integer :major_version
          integer :minor_version
        end
      end
      # END LEGACY SHIM ========================================================
    end

    def validate
      add_error :log, :private, BAD_WORDS if has_bad_words
      add_error :device, :no_id, "ID of device can't be nil" unless device.id
      @log               = Log.new
      @log.device_id     = device.id
      @log.message       = message
      @log.channels      = channels || []
      @log.x             = transitional_field(:x)
      @log.y             = transitional_field(:y)
      @log.z             = transitional_field(:z)
      @log.verbosity     = transitional_field(:verbosity, 1)
      @log.major_version = transitional_field(:major_version)
      @log.minor_version = transitional_field(:minor_version)
      @log.type          = transitional_field(:type, "info")
      @log.validate!
    end

    def execute
      @log.save! && maybe_deliver
      @log
    end

    private
<commit_msg>Add `created_at` to Log::Create. NEXT: Tests<commit_after>module Logs
  class Create < Mutations::Command
    BLACKLIST = /WPA|PSK|PASSWORD|NERVES/
    BAD_WORDS = "Log message contained blacklisted words"

    required do
      # TODO: Some strange stuff happened with caching in the log service.
      #       Had to change this from "model" to "duck" as a result.
      #       See Device#refresh_cache(). Rails thinks cached `Device` objects
      #       are unsaved.
      duck  :device, methods: [:id, :is_device]
      string :message
    end

    optional do
      array :channels,
            class: String,
            in: CeleryScriptSettingsBag::ALLOWED_CHANNEL_NAMES
      # LEGACY SHIM AHEAD!!! ===================================================
      #
      # We once stored certain fields in a `meta` column.
      # The API has evolved since that time, the requirements are pretty solid
      # at this point and we need the ability to perform SQL queries. The `meta`
      # field is no longer useful nor is it a clean solution.
      #
      # Legacy FBOS versions expect logs to be in the same shape as before
      # and they also produce logs with the expectation that logs have a `meta`
      # field.
      #
      # We will keep the `meta` field around for now, but ideally, API users
      # should access `log.FOO` instead of `log.meta.FOO` for future
      # compatibility.
      #
      # TODO: delete the `meta` field once FBOS < v6.4.0 reach EOL.
      string  :type, in: Log::TYPES
      integer :x
      integer :y
      integer :z
      integer :verbosity
      integer :major_version
      integer :minor_version
      integer :created_at

      hash :meta do # This can be transitioned out soon.
        string :type, in: Log::TYPES
        optional do
          integer :x
          integer :y
          integer :z
          integer :verbosity
          integer :major_version
          integer :minor_version
        end
      end
      # END LEGACY SHIM ========================================================
    end

    def validate
      add_error :log, :private, BAD_WORDS if has_bad_words
      add_error :device, :no_id, "ID of device can't be nil" unless device.id
      @log               = Log.new
      @log.device_id     = device.id
      @log.message       = message
      @log.channels      = channels || []
      @log.x             = transitional_field(:x)
      @log.y             = transitional_field(:y)
      @log.z             = transitional_field(:z)
      @log.verbosity     = transitional_field(:verbosity, 1)
      @log.major_version = transitional_field(:major_version)
      @log.minor_version = transitional_field(:minor_version)
      @log.type          = transitional_field(:type, "info")
      @log.created_at    = DateTime.strptime(created_at.to_s,'%s') if created_at
      @log.validate!
    end

    def execute
      @log.save! && maybe_deliver
      @log
    end

    private

{'fraction_non_alphanumeric': 0.11230502599653379, 'fraction_numerical': 0.0013864818024263432, 'mean_word_length': 2.1570021881838075, 'pattern_counts': {'":': 0, '<': 7, '<?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': '3074053', 'n_tokens_mistral': 1647, 'n_tokens_neox': 1586, 'n_words': 553}