lib/baz_venue_adapter_open_sea/fetch_collection_by_slug.ex

defmodule BazVenueAdapterOpenSea.FetchCollectionBySlug do
  @moduledoc """
  Implementation of the Baz.VenueAdapter.fetch_collection_by_slug/2 callback
  """

  alias BazVenueAdapterOpenSea.Credentials
  alias BazVenueAdapterOpenSea.ApiClient

  @type venue :: Baz.VenueAdapter.venue()
  @type slug :: Baz.VenueAdapter.collection_slug()
  @type result :: Baz.VenueAdapter.fetch_collection_by_slug_result()

  @spec fetch_collection_by_slug(venue, slug) :: result
  def fetch_collection_by_slug(venue, slug) do
    {venue, slug}
    |> with_api_key()
    |> fetch()
    |> write_to_raw_sinks()
    |> build_changset()
  end

  defp with_api_key({venue, slug}) do
    case Credentials.get_api_key(venue.credentials) do
      {:ok, api_key} -> {venue, slug, api_key}
      {:error, :not_found} -> {:error, :api_key_not_found}
    end
  end

  defp fetch({venue, slug, api_key}) do
    api_result = ApiClient.fetch_collection_by_slug(slug, api_key)
    {venue, slug, api_key, api_result}
  end

  defp fetch({:error, _reason} = error), do: error

  defp write_to_raw_sinks({venue, slug, _api_key, api_result} = args) do
    :ok = Baz.Sinks.write_raw(:collections, venue, slug, api_result)
    args
  end

  defp write_to_raw_sinks({:error, _reason} = error), do: error

  defp build_changset({venue, slug, _api_key, api_result}) do
    case api_result do
      {:ok, venue_collection, _} ->
        {venue, slug, venue_collection}
        |> build_attrs()
        |> Baz.Collections.collection_changeset()

      {:error, reason, _} ->
        {:error, reason}
    end
  end

  defp build_changset({:error, _reason} = error), do: error

  defp build_attrs({venue, slug, venue_collection}) do
    # TODO: enumerate collection traits and save
    %{
      venue: venue.name,
      slug: slug,
      name: venue_collection.name,
      description: venue_collection.description,
      image_uri: venue_collection.image_url,
      banner_image_uri: venue_collection.banner_image_url
    }
  end
end