defmodule Ibex.Messages.Types do
  @type message_type :: atom()
  @type code_map :: map()
  @type market_data_type :: :bid | :ask | :trades
  @type ticker_id :: integer()

  defmodule Inbound do
    @type message_type :: Ibex.Messages.Types.message_type()
    @codes %{
      1 => :tick_price,
      2 => :tick_size,
      3 => :order_status,
      4 => :err_msg,
      5 => :open_order,
      6 => :acct_value,
      7 => :portfolio_value,
      8 => :acct_update,
      9 => :next_valid,
      10 => :contract_data,
      11 => :execution_data,
      12 => :market_depth,
      13 => :market_depth,
      14 => :news_bulletins,
      15 => :managed_accts,
      16 => :receive_fa,
      17 => :historical_data,
      18 => :bond_contract,
      19 => :scanner_parameters,
      20 => :scanner_data,
      21 => :tick_option,
      45 => :tick_generic,
      46 => :tick_string,
      47 => :tick_efp,
      49 => :current_time,
      50 => :real_time_bars,
      51 => :fundamental_data,
      52 => :contract_data_end,
      53 => :open_order_end,
      54 => :acct_download_end,
      55 => :execution_data_end,
      56 => :delta_neutral_validation,
      57 => :tick_snapshot_end,
      58 => :market_data_type,
      59 => :commission_report,
      61 => :position_data,
      62 => :position_end,
      63 => :account_summary,
      64 => :account_summary_end,
      65 => :verify_message_api,
      66 => :verify_completed,
      67 => :display_group_list,
      68 => :display_group_updated,
      69 => :verify_and_auth_message_api,
      70 => :verify_and_auth_completed,
      71 => :position_multi,
      72 => :position_multi_end,
      73 => :account_update_multi,
      74 => :account_update_multi_end,
      75 => :security_definition_option_parameter,
      76 => :security_definition_option_parameter_end,
      77 => :soft_dollar_tiers,
      78 => :family_codes,
      79 => :symbol_samples,
      80 => :mkt_depth_exchanges,
      81 => :tick_req_params,
      82 => :smart_components,
      83 => :news_article,
      84 => :tick_news,
      85 => :news_providers,
      86 => :historical_news,
      87 => :historical_news_end,
      88 => :head_timestamp,
      89 => :histogram_data,
      90 => :historical_data_update,
      91 => :reroute_mkt_data_req,
      92 => :reroute_mkt_depth_req,
      93 => :market_rule,
      94 => :pnl,
      95 => :pnl_single,
      96 => :historical_ticks,
      97 => :historical_ticks_bid_ask,
      98 => :historical_ticks_last,
      99 => :tick_by_tick,
      100 => :order_bound,
      101 => :completed_order,
      102 => :completed_orders_end,
      103 => :replace_fa_end,
      104 => :wsh_meta_data,
      105 => :wsh_event_data,
      106 => :historical_schedule,
      107 => :user_info
    }

    @spec parse(integer()) :: message_type()
    def parse(code) do
      Map.get(@codes, code, nil)
    end
  end

  defmodule Outbound do
    @type message_type :: Ibex.Messages.Types.message_type()
    @codes %{
      :req_mkt_data => 1,
      :cancel_mkt_data => 2,
      :place_order => 3,
      :cancel_order => 4,
      :req_open_orders => 5,
      :req_acct_data => 6,
      :req_executions => 7,
      :req_ids => 8,
      :req_contract_data => 9,
      :req_mkt_depth => 10,
      :cancel_mkt_depth => 11,
      :req_news_bulletins => 12,
      :cancel_news_bulletins => 13,
      :set_server_loglevel => 14,
      :req_auto_open_orders => 15,
      :req_all_open_orders => 16,
      :req_managed_accts => 17,
      :req_fa => 18,
      :replace_fa => 19,
      :req_historical_data => 20,
      :exercise_options => 21,
      :req_scanner_subscription => 22,
      :cancel_scanner_subscription => 23,
      :req_scanner_parameters => 24,
      :cancel_historical_data => 25,
      :req_current_time => 49,
      :req_real_time_bars => 50,
      :cancel_real_time_bars => 51,
      :req_fundamental_data => 52,
      :cancel_fundamental_data => 53,
      :req_calc_implied_volat => 54,
      :req_calc_option_price => 55,
      :cancel_calc_implied_volat => 56,
      :cancel_calc_option_price => 57,
      :req_global_cancel => 58,
      :req_market_data_type => 59,
      :req_positions => 61,
      :req_account_summary => 62,
      :cancel_account_summary => 63,
      :cancel_positions => 64,
      :verify_request => 65,
      :verify_message => 66,
      :query_display_groups => 67,
      :subscribe_to_group_events => 68,
      :update_display_group => 69,
      :unsubscribe_from_group_events => 70,
      :start_api => 71,
      :verify_and_auth_request => 72,
      :verify_and_auth_message => 73,
      :req_positions_multi => 74,
      :cancel_positions_multi => 75,
      :req_account_updates_multi => 76,
      :cancel_account_updates_multi => 77,
      :req_sec_def_opt_params => 78,
      :req_soft_dollar_tiers => 79,
      :req_family_codes => 80,
      :req_matching_symbols => 81,
      :req_mkt_depth_exchanges => 82,
      :req_smart_components => 83,
      :req_news_article => 84,
      :req_news_providers => 85,
      :req_historical_news => 86,
      :req_head_timestamp => 87,
      :req_histogram_data => 88,
      :cancel_histogram_data => 89,
      :cancel_head_timestamp => 90,
      :req_market_rule => 91,
      :req_pnl => 92,
      :cancel_pnl => 93,
      :req_pnl_single => 94,
      :cancel_pnl_single => 95,
      :req_historical_ticks => 96,
      :req_tick_by_tick_data => 97,
      :cancel_tick_by_tick_data => 98,
      :req_completed_orders => 99,
      :req_wsh_meta_data => 100,
      :cancel_wsh_meta_data => 101,
      :req_wsh_event_data => 102,
      :cancel_wsh_event_data => 103,
      :req_user_info => 104
    }

    @spec parse(message_type()) :: integer()
    def parse(mtype) do
      Map.get(@codes, mtype, nil)
    end
  end
end