module ContentfulMiddleman
  class ImportTask
    def initialize(space_name, content_type_names, content_type_mappers, contentful)
      @space_name           = space_name
      @content_type_names   = content_type_names
      @content_type_mappers = content_type_mappers
      @changed_local_data   = false
      @contentful           = contentful
      @use_camel_case       = @contentful.options.client_options.fetch(:use_camel_case, false)
    end

    def run
      old_version_hash = ContentfulMiddleman::VersionHash.read_for_space(@space_name)

      LocalData::Store.new(local_data_files, @space_name).write

      new_version_hash = ContentfulMiddleman::VersionHash.write_for_space_with_entries(@space_name, entries, @use_camel_case)

      @changed_local_data = new_version_hash != old_version_hash
    end

    def changed_local_data?
      @changed_local_data
    end

    def entries
      @entries ||= @contentful.entries
    end

    def file_name(content_type_name, entry)
      entry_id = entry.sys.key?(:id) ? entry.sys[:id] : entry.id
      File.join(@space_name, content_type_name, entry_id.to_s)
    end

    private
    def local_data_files
      content_type_key = if @use_camel_case
                           :contentType
                         else
                           :content_type
                         end

      entries.map do |entry|
        content_type_mapper_class = @content_type_mappers.fetch(entry.sys[content_type_key].id, nil)

        next unless content_type_mapper_class

        content_type_name = @content_type_names.fetch(entry.sys[content_type_key].id).to_s
        context = ContentfulMiddleman::Context.new

        content_type_mapper = content_type_mapper_class.new(entries, @contentful.options)
        content_type_mapper.map(context, entry)

        LocalData::File.new(context.to_yaml, file_name(content_type_name, entry))
      end.compact
    end
  end
end
