# frozen_string_literal: true

module Litany
  class Enum
    class << self
      def inherited(child)
        child.forward_store = forward_store.clone unless self == Enum
        child.reverse_store = reverse_store.clone unless self == Enum
        child.metadata_store = metadata_store.clone unless self == Enum
      end

      def add(index, token, metadata = {})
        raise "Index `#{index}` already added" if valid_index? index
        raise "Token `#{token}` already added" if valid_token? token

        forward_store[index] = token
        reverse_store[token] = index
        metadata_store[token] = metadata
      end

      def valid_token?(token)
        reverse_store.include? token
      end

      def valid_index?(index)
        forward_store.include? index
      end

      def token(index)
        raise "No Token for Index `#{index}`" unless valid_index? index
        forward_store[index]
      end

      def index(token)
        raise "No Index for Token `#{token}`" unless valid_token? token
        reverse_store[token]
      end

      def rand_token
        reverse_store.keys.sample
      end

      def rand_index
        forward_store.keys.sample
      end

      protected

      attr_writer :forward_store, :reverse_store, :metadata_store

      def forward_store
        @forward_store ||= {}
      end

      def reverse_store
        @reverse_store ||= {}
      end

      def metadata_store
        @metadata_store ||= {}
      end
    end
  end
end
