xhr      = require('xhr')
_          = require('lodash')
dispatcher = require('../../common/js/dispatcher')
utils = require('../../common/js/utils.coffee')
metrics = require('../../common/js/metrics.coffee')
settings = require('../../../config/settings').settings

TRIES_LIMIT = 3
SEARCH_RESULTS_URL = settings.host + "/new_searches_results_united"
SEARCH_REQUEST_URL = settings.host + "/new_adaptors/chains/"

module.exports = (request_params, callbacks = {}) ->

    #private
    callbacks = _.extend({
      "on_update": ->
      "on_finish": ->
      "on_error" : ->
      "on_abort" : ->
    }, callbacks)

    search_uuid = null
    _xhr        = null
    tries_count = 0

    abort = -> _xhr?.abort()

    stop_marker_received = (data) ->
      stop_marker = (_.isObject(data) and _.keys(data).length == 1)
      _.isString(data) or _.isNull(data) or stop_marker

    failed_with_500 = (res) ->
      not res or res?.statusCode.toString()[0] == '5'

    get_search_url = (search_uuid = null) ->
      if search_uuid
        url = "#{SEARCH_RESULTS_URL}?uuid=#{search_uuid}&#{Math.random()}"
      else
        chain = if utils.is_open_jaw(request_params.segments) then 'jetradar_rt_openjaw' else 'jetradar_rt_search_native_format'
        url = SEARCH_REQUEST_URL + chain
      url

    on_receive = (req_params, err, res) =>
      return callbacks.on_abort() if res?.abort
      return if res?.statusCode == 0

      if res?.statusCode is 200
        tries_count = 0
        if res?.body?.meta?.uuid
          search_uuid = res.body.meta.uuid
        data = []
        for item, index in [].concat(res.body)
          if stop_marker_received(item)
            callbacks.on_update(data)
            callbacks.on_finish()
            return
          data.push(item)
        callbacks.on_update(data)
        send_request(get_search_url(search_uuid))
      else
        if tries_count < TRIES_LIMIT and failed_with_500(res)
          dispatcher.send('log_warning', "Trying to reconnect #{tries_count} times", 'yasen_client')
          send_request(res.url, res.method, req_params)
        else
          callbacks.on_error({status: res?.statusCode})

        metrics.reach_goal('SEARCH_RESPONSE_ERROR', {status: res?.statusCode})

    send_request = (url, method = "get", request_params = {}) ->
      tries_count++
      _xhr = xhr({
          url: url
          json: request_params
          method: method
        }, _.partial(on_receive, request_params))

    send_request(get_search_url(), "post", request_params)


    #public
    stop: -> abort()
