# defmodule HL7.SplitStream do
#  @moduledoc false
#
#  require Logger
#
#  @type prefix :: String.t() | Regex.t() | nil
#  @type suffix :: String.t() | Regex.t()
#
#  @spec raw_to_messages(Enumerable.t(), prefix(), suffix()) :: Enumerable.t()
#  def raw_to_messages(input_stream, prefix, suffix) do
#    chunker = get_chunker(prefix, suffix)
#    Stream.chunk_while(input_stream, "", chunker, &after_chunking/1) |> Stream.concat()
#  end
#
#  @spec get_after_prefix(prefix()) :: function()
#  defp get_after_prefix(nil) do
#    fn text -> text end
#  end
#
#  defp get_after_prefix(prefix) when is_binary(prefix) do
#    fn text ->
#      chunks = text |> String.split(prefix, parts: 2)
#
#      case chunks do
#        [_chunk] -> nil
#        [_sb, msg] -> msg
#      end
#    end
#  end
#
#  defp get_after_prefix(%Regex{} = prefix) do
#    fn text ->
#      chunks = Regex.split(prefix, text, parts: 2)
#
#      case chunks do
#        [_chunk] -> nil
#        [_sb, msg] -> msg
#      end
#    end
#  end
#
#  @spec get_split_on_suffix(suffix()) :: (binary() -> [binary()])
#  defp get_split_on_suffix(suffix) when is_binary(suffix) do
#    fn text -> String.split(text, suffix) end
#  end
#
#  defp get_split_on_suffix(%Regex{} = suffix) do
#    fn text -> Regex.split(suffix, text, trim: true) end
#  end
#
#  @spec get_chunker(String.t(), Regex.t()) :: function()
#  defp get_chunker(prefix, suffix) do
#    to_list_and_remnant = get_to_list_and_remnant(prefix)
#    split_on_suffix = get_split_on_suffix(suffix)
#
#    fn
#      element, acc when is_binary(element) ->
#        # {:cont, chunk, acc} | {:cont, acc} | {:halt, acc})
#
#        text = acc <> element
#        potential_msg_list = split_on_suffix.(text)
#
#        case potential_msg_list do
#          [not_found] -> {:cont, not_found}
#          _ -> to_list_and_remnant.(potential_msg_list)
#        end
#
#      _element, _acc ->
#        raise(ArgumentError, message: "all elements in an HL7 stream must be binary")
#    end
#  end
#
#  @spec get_to_list_and_remnant(prefix()) :: function()
#  defp get_to_list_and_remnant(prefix) do
#    after_prefix = get_after_prefix(prefix)
#
#    fn potential_messages ->
#      [remnant | reverse_msgs] = potential_messages |> Enum.reverse()
#
#      msgs =
#        reverse_msgs
#        |> Enum.map(fn m -> after_prefix.(m) end)
#        |> Enum.filter(fn m -> is_binary(m) and m != "" end)
#        |> Enum.reverse()
#
#      {:cont, msgs, remnant}
#    end
#  end
#
#  defp after_chunking(_acc) do
#    {:cont, []}
#  end
# end
