from __future__ import absolute_import
import os
import json
import six


class CopyError(Exception):
    pass


class SpiderCopier(object):
    """
    Utility for copying spiders and items from one project to another.

    :source: read data from source project in read_file
    :destination: read and write to destination project in read_file and
                  save_files
    """
    def __init__(self, source, destination):
        self.source = source
        self.source_files = set(self.list_files(source))
        self.destination = destination
        self.destination_files = set(self.list_files(destination))

    def _spider_path(self, spider):
        return 'spiders/%s.json' % spider

    def copy(self, spiders, items=None):
        """
        Copies the provided spiders and items from the source project to the
        destination project. If spiders have name collisions the copied spider
        will be renamed. In the event of item name collisions a merge will be
        attempted.

        :list spiders: List of spiders to copy from the source to the
                       destination
        :list items: optional: List of items to copy that may not be scraped
                               by the provided spiders
        raises CopyError
        """
        if items is None:
            items = []
        spider_paths = set(self._spider_path(s) for s in spiders)
        self._check_missing(spider_paths)
        templates = self._load_templates(spiders)
        combined_items, renamed_items = \
            self._build_combined_items(templates, items)
        spider_data, renamed_spiders = self._load_spiders(spider_paths)
        templates = self._update_templates(templates, renamed_items,
                                           renamed_spiders)
        extractors = self._build_combined_extractors(templates)
        self._save_data({
            'items.json': combined_items,
            'extractors.json': extractors,
            'spiders': spider_data,
            'templates': templates,
        })
        return self._build_summary(spider_paths, items,
                                   renamed_spiders, renamed_items)

    def _refresh_destination_files(self):
        self.destination_files = set(self.list_files(self.destination))

    def _check_missing(self, spider_paths):
        """
        Check if any of the provided spiders don't exist.
        """