class Multiwoven::Integrations::Destination::Slack::Client

def build_args(stream_name, record)

def build_args(stream_name, record)
  case stream_name
  when "chat_postMessage"
    { channel: channel_id, text: slack_code_block(record) }
  else
    raise "Stream name not found: #{stream_name}"
  end
end

def check_connection(connection_config)

def check_connection(connection_config)
  configure_slack(connection_config[:api_token])
  client = ::Slack::Web::Client.new
  client.auth_test
  success_status
rescue StandardError => e
  failure_status(e)
end

def configure_slack(api_token)

def configure_slack(api_token)
  ::Slack.configure do |config|
    config.token = api_token
  end
end

def discover(_connection_config = nil)

def discover(_connection_config = nil)
  catalog = build_catalog(load_catalog)
  catalog.to_multiwoven_message
rescue StandardError => e
  handle_exception(e, {
                     context: "SLACK:DISCOVER:EXCEPTION",
                     type: "error"
                   })
end

def failure_status(error)

def failure_status(error)
  ConnectionStatus.new(status: ConnectionStatusType["failed"], message: error.message).to_multiwoven_message
end

def load_catalog

def load_catalog
  read_json(CATALOG_SPEC_PATH)
end

def process_record(stream, record)

def process_record(stream, record)
  send_data_to_slack(stream[:name], record)
end

def process_records(records, stream)

def process_records(records, stream)
  write_success = 0
  write_failure = 0
  records.each do |record_object|
    process_record(stream, record_object.with_indifferent_access)
    write_success += 1
  rescue StandardError => e
    write_failure += 1
    handle_exception(e, {
                       context: "SLACK:WRITE:EXCEPTION",
                       type: "error",
                       sync_id: @sync_config.sync_id,
                       sync_run_id: @sync_config.sync_run_id
                     })
  end
  tracking_message(write_success, write_failure)
end

def send_data_to_slack(stream_name, record = {})

def send_data_to_slack(stream_name, record = {})
  args = build_args(stream_name, record)
  @client.send(stream_name, **args)
end

def slack_code_block(data)

def slack_code_block(data)
  longest_key = data.keys.map(&:to_s).max_by(&:length).length
  table_str = "```\n"
  data.each do |key, value|
    table_str += "#{key.to_s.ljust(longest_key)} : #{value}\n"
  end
  table_str += "```"
  table_str
end

def success_status

def success_status
  ConnectionStatus.new(status: ConnectionStatusType["succeeded"]).to_multiwoven_message
end

def tracking_message(success, failure)

def tracking_message(success, failure)
  Multiwoven::Integrations::Protocol::TrackingMessage.new(
    success: success, failed: failure
  ).to_multiwoven_message
end

def write(sync_config, records, action = "create")

def write(sync_config, records, action = "create")
  # Currently as we only create a message for each record in slack, we are not using actions.
  # This will be changed in future.
  @sync_config = sync_config
  @action = sync_config.stream.action || action
  connection_config = sync_config.destination.connection_specification.with_indifferent_access
  configure_slack(connection_config[:api_token])
  @client = ::Slack::Web::Client.new
  @channel_id = connection_config[:channel_id]
  process_records(records, sync_config.stream)
rescue StandardError => e
  handle_exception(e, {
                     context: "SLACK:WRITE:EXCEPTION",
                     type: "error",
                     sync_id: @sync_config.sync_id,
                     sync_run_id: @sync_config.sync_run_id
                   })
end