<commit_before>defmodule Poxa.WebsocketHandler do
  @moduledoc """
  This module contains Cowboy Websocket handler callbacks to requests on /apps/:app_key

  More info on Cowboy HTTP handler at: http://ninenines.eu/docs/en/cowboy/HEAD/guide/ws_handlers

  More info on Pusher protocol at: http://pusher.com/docs/pusher_protocol
  """
  require Lager
  alias Poxa.PusherEvent
  alias Poxa.PresenceSubscription
  alias Poxa.Subscription

  def init(_transport, _req, _opts), do: {:upgrade, :protocol, :cowboy_websocket}

  def websocket_init(_transport_name, req, _opts) do
    {app_key, req} = :cowboy_req.binding(:app_key, req)
    case :application.get_env(:poxa, :app_key) do
      {:ok, ^app_key} ->
        self <- :start
        {:ok, req, nil}
      _ ->
        Lager.error('Invalid app_key, expected ~p, found ~p',
          [:application.get_env(:poxa, :app_key), app_key])
        {:shutdown, req, nil}
    end
  end

  def websocket_handle({:text, json}, req, state) do
    JSEX.decode!(json)
      |> handle_pusher_event(req, state)
  end

  def handle_pusher_event(decoded_json, req, state) do
    ListDict.get(decoded_json, "event")
    |> handle_pusher_event(decoded_json, req, state)
  end

  defp handle_pusher_event("pusher:subscribe", decoded_json, req, state) do
    data = ListDict.get(decoded_json, "data")
    reply = case Subscription.subscribe!(data, state) do
      :ok -> PusherEvent.subscription_succeeded
      {:presence, channel, presence_data} -> PusherEvent.presence_subscription_succeeded(channel, presence_data)
      :error -> PusherEvent.subscription_error
    end
    {:reply, {:text, reply}, req, state}
  end
  defp handle_pusher_event("pusher:unsubscribe", decoded_json, req, state) do
    :ok = ListDict.get(decoded_json, "data")
      |> Subscription.unsubscribe!
    {:ok, req, state}
  end
  defp handle_pusher_event("pusher:ping", _decoded_json, req, state) do
    reply = PusherEvent.pong
    {:reply, {:text, reply}, req, state}
  end
  # Client Events
  defp handle_pusher_event("client-" <> _event_name = _event, decoded_json, req, state) do
    {message, channels, _exclude} = PusherEvent.parse_channels(decoded_json)
    lc channel inlist channels, private_or_presence_channel(channel), Subscription.subscribed?(channel) do
      PusherEvent.send_message_to_channel(channel, message, [self])
    end
    {:ok, req, state}
  end
  defp handle_pusher_event(_, _data, req, state) do
    Lager.info("Undefined event")
    {:ok, req, state}
  end

  defp private_or_presence_channel(channel) do
    case channel do
      "presence-" <> _presence_channel -> true
      "private-" <> _private_channel -> true
      _ -> false
    end
  end<commit_msg>Remove ListDict.get and use access protocol<commit_after>defmodule Poxa.WebsocketHandler do
  @moduledoc """
  This module contains Cowboy Websocket handler callbacks to requests on /apps/:app_key

  More info on Cowboy HTTP handler at: http://ninenines.eu/docs/en/cowboy/HEAD/guide/ws_handlers

  More info on Pusher protocol at: http://pusher.com/docs/pusher_protocol
  """
  require Lager
  alias Poxa.PusherEvent
  alias Poxa.PresenceSubscription
  alias Poxa.Subscription

  def init(_transport, _req, _opts), do: {:upgrade, :protocol, :cowboy_websocket}

  def websocket_init(_transport_name, req, _opts) do
    {app_key, req} = :cowboy_req.binding(:app_key, req)
    case :application.get_env(:poxa, :app_key) do
      {:ok, ^app_key} ->
        self <- :start
        {:ok, req, nil}
      _ ->
        Lager.error('Invalid app_key, expected ~p, found ~p',
          [:application.get_env(:poxa, :app_key), app_key])
        {:shutdown, req, nil}
    end
  end

  def websocket_handle({:text, json}, req, state) do
    JSEX.decode!(json)
      |> handle_pusher_event(req, state)
  end

  def handle_pusher_event(decoded_json, req, state) do
    handle_pusher_event(decoded_json["event"], decoded_json, req, state)
  end

  defp handle_pusher_event("pusher:subscribe", decoded_json, req, state) do
    data = decoded_json["data"]
    reply = case Subscription.subscribe!(data, state) do
      :ok -> PusherEvent.subscription_succeeded
      {:presence, channel, presence_data} -> PusherEvent.presence_subscription_succeeded(channel, presence_data)
      :error -> PusherEvent.subscription_error
    end
    {:reply, {:text, reply}, req, state}
  end
  defp handle_pusher_event("pusher:unsubscribe", decoded_json, req, state) do
    :ok = Subscription.unsubscribe! decoded_json["data"]
    {:ok, req, state}
  end
  defp handle_pusher_event("pusher:ping", _decoded_json, req, state) do
    reply = PusherEvent.pong
    {:reply, {:text, reply}, req, state}
  end
  # Client Events
  defp handle_pusher_event("client-" <> _event_name = _event, decoded_json, req, state) do
    {message, channels, _exclude} = PusherEvent.parse_channels(decoded_json)
    lc channel inlist channels, private_or_presence_channel(channel), Subscription.subscribed?(channel) do
      PusherEvent.send_message_to_channel(channel, message, [self])
    end
    {:ok, req, state}
  end
  defp handle_pusher_event(_, _data, req, state) do
    Lager.info("Undefined event")
    {:ok, req, state}
  end

  defp private_or_presence_channel(channel) do
    case channel do
      "presence-" <> _presence_channel -> true
      "private-" <> _private_channel -> true
      _ -> false
    end
  end
{'fraction_non_alphanumeric': 0.11481826654240447, 'fraction_numerical': 0.0, 'mean_word_length': 3.900456621004566, 'pattern_counts': {'":': 0, '<': 11, '<?xml version=': 0, '>': 29, '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': '5260345', 'n_tokens_mistral': 1865, 'n_tokens_neox': 1857, 'n_words': 431}