<commit_before>{Resource} = require "./resource"
{EventEmitter} = require "./events"

class ActionResource extends Resource
  
  constructor: (data, self) ->
    super data, self

  root: ->
    @_root or @_root = Object.keys(@constructor.schema())[0]
    @data[@_root] if @data

  requestId: ->
    @root()["@requestId"] if @root()

exports.ActionCommand = class ActionCommand extends ActionResource
  
  @can "create"

exports.ActionResult = class ActionResult extends ActionResource
  
  @can "load"

  requestState: ->
    @root().requestState if @root()

  completionStatus: ->
    @root().completionStatus if @root()

  failureMessage: ->
    @root().failureMessage if @root()

  result: ->
    @root().result if @root()

class Meta

  metas = {}
  
  metaFor = (T) ->
    name = T.name
    metas[name] = {} if not metas[name]
    metas[name]
  
  @metaprop: (def) ->
    k = Math.random().toString()
    (v) -> if v? then (metaFor @)[k] = v else (metaFor @)[k] or def

exports.Action = class Action extends Meta

  @command: @metaprop()

  @result: @metaprop()

  @schedule: @metaprop (250 for i in [1..16]).concat(500 for i in [1..16]).concat(1000 for i in [1..18])

  constructor: (@config={}) ->

  invoke: (options) ->
    start = Date.now()
    events = new EventEmitter
    events.names = "ready"
    schedule = @constructor.schedule()
    command = @constructor.command()
    result = @constructor.result()
    created = (cmodel) =>
      poll = (attempt=0) =>
        loaded = (lmodel) =>
          if lmodel.requestState() is "Completed"
            events.emit "ready", lmodel, Date.now() - start
          else
            if attempt < schedule.length
              doAttempt = -> poll attempt + 1
              setTimeout doAttempt, schedule[attempt]
            else
              events.emit "error", new Error "Maximum number of retries exceeded while polling for action result"
        label = "Poll for action result (#{attempt + 1})"
        result.load(requestId: cmodel.requestId(), oauth: options.oauth, trace: label)
          .on("loaded", loaded)
          .forward(events, "error send receive trace")
      poll()
    opts = {}
    opts[k] = v for own k, v of src for src in [@config, options]
    command.create(opts)
      .on("created", created)
      .forward(events)
    events

exports.ActionProxy = class ActionProxy extends Meta
  
  @getter: @metaprop()
  <commit_msg>Simplification of event emitter construction<commit_after>{Resource} = require "./resource"
{EventEmitter} = require "./events"

class ActionResource extends Resource
  
  constructor: (data, self) ->
    super data, self

  root: ->
    @_root or @_root = Object.keys(@constructor.schema())[0]
    @data[@_root] if @data

  requestId: ->
    @root()["@requestId"] if @root()

exports.ActionCommand = class ActionCommand extends ActionResource
  
  @can "create"

exports.ActionResult = class ActionResult extends ActionResource
  
  @can "load"

  requestState: ->
    @root().requestState if @root()

  completionStatus: ->
    @root().completionStatus if @root()

  failureMessage: ->
    @root().failureMessage if @root()

  result: ->
    @root().result if @root()

class Meta

  metas = {}
  
  metaFor = (T) ->
    name = T.name
    metas[name] = {} if not metas[name]
    metas[name]
  
  @metaprop: (def) ->
    k = Math.random().toString()
    (v) -> if v? then (metaFor @)[k] = v else (metaFor @)[k] or def

exports.Action = class Action extends Meta

  @command: @metaprop()

  @result: @metaprop()

  @schedule: @metaprop (250 for i in [1..16]).concat(500 for i in [1..16]).concat(1000 for i in [1..18])

  constructor: (@config={}) ->

  invoke: (options) ->
    start = Date.now()
    events = new EventEmitter "ready"
    schedule = @constructor.schedule()
    command = @constructor.command()
    result = @constructor.result()
    created = (cmodel) =>
      poll = (attempt=0) =>
        loaded = (lmodel) =>
          if lmodel.requestState() is "Completed"
            events.emit "ready", lmodel, Date.now() - start
          else
            if attempt < schedule.length
              doAttempt = -> poll attempt + 1
              setTimeout doAttempt, schedule[attempt]
            else
              events.emit "error", new Error "Maximum number of retries exceeded while polling for action result"
        label = "Poll for action result (#{attempt + 1})"
        result.load(requestId: cmodel.requestId(), oauth: options.oauth, trace: label)
          .on("loaded", loaded)
          .forward(events, "error send receive trace")
      poll()
    opts = {}
    opts[k] = v for own k, v of src for src in [@config, options]
    command.create(opts)
      .on("created", created)
      .forward(events)
    events

exports.ActionProxy = class ActionProxy extends Meta
  
  @getter: @metaprop()
  
{'fraction_non_alphanumeric': 0.13995859213250517, 'fraction_numerical': 0.009523809523809525, 'mean_word_length': 2.6821646341463414, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 35, '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': '4648028', 'n_tokens_mistral': 1522, 'n_tokens_neox': 1458, 'n_words': 433}