'''
Implementacja pamięci trwałej dla aplikacji Modny ciuch
Obiekty StockItem mogą być przechowywane i odkrywane na podstawie
właściwości tag, która identyfikuje zbiór atrybutów
dla tego towaru.
'''

import pickle

from  Storage.StockItem import StockItem

class FashionShop:

    show_instrumentation = False

    min_price = 0.5 
    max_price = 500.0 

    max_stock_add = 50

    def __init__(self):
        if FashionShop.show_instrumentation:
            print('** Wywołano metodę __init__ klasy FashionShop')
        self.__stock_dictionary = {}

    def save(self, filename):
        '''
        Zapisuje dane sklepu w pliku o podanej nazwie
        Dane są przechowywane w postaci binarnej, w pliku .pickle
        Jeśli zapis nie powiedzie się, program zgłosi wyjątki 
        '''
        if FashionShop.show_instrumentation:
            print('** Wywołano metodę save klasy FashionShop')
        with open(filename,'wb') as out_file:
            pickle.dump(self,out_file)

    @staticmethod
    def load(filename):
        '''
        Ładuje dane sklepu z odzieżą z pliku o podanej nazwie
        Dane są przechowywane w postaci binarnej, w pliku .pickle
        Jeśli ładowanie pliku się nie powiedzie, funkcja będzie zgłaszała wyjątki
        '''
        if FashionShop.show_instrumentation:
            print('** Wywołano metodę load klasy FashionShop')
        with open(filename,'rb') as input_file:
            result = pickle.load(input_file)

        # Teraz zaktualizuj wersje załadowanych towarów
        for stock_item in result.__stock_dictionary.values():
            stock_item.check_version()
        return result


    def store_new_stock_item(self, stock_item):
        '''
        Utwórz nowy towar w sklepie z odzieżą
        Towary są poindeksowane wg wartości stock_ref
        Zgłasza wyjątek, jeśli towar już 
        istnieje 
        '''
        if FashionShop.show_instrumentation:
            print('** Wywołano metodę store_new_stock_item klasy FashionShop')
        if stock_item.stock_ref in self.__stock_dictionary:
            raise Exception('Towar już istnieje') 
        self.__stock_dictionary[stock_item.stock_ref] = stock_item


    def find_stock_item(self, stock_ref):
        '''
        Pobiera towar ze słownika
        Zwraca None, jeśli nie ma towaru dla
        tego klucza
        '''
        if FashionShop.show_instrumentation:
            print('** Wywołano metodę find_stock_item klasy FashionShop')
        if stock_ref in self.__stock_dictionary:
            return self.__stock_dictionary[stock_ref]
        else:
            return None

    def __str__(self):
        if FashionShop.show_instrumentation:
            print('** Wywołano metodę __str__ klasy FashionShop')
        stock = map(str,self.__stock_dictionary.values())
        stock_list = '\n'.join(stock)
        template = '''Towary w magazynie

{0}
'''
        return template.format(stock_list)

    def find_matching_with_tags(self, search_tags):
        '''
        Zwraca pozycje magazynowe, które zawierają
        w zbiorze znaczników znaczniki search_tags
        '''
        if FashionShop.show_instrumentation:
            print('** Wywołano metodę find_matching_tags klasy FashionShop', search_tags)

        def match_tags(item):
            '''
            Zwraca True jeśli znaczniki towaru
            zawierają znaczniki poszukiwane
            '''
            return search_tags.issubset(item.tags)

        return filter(lambda item:search_tags.issubset(item.tags), self.__stock_dictionary.values())
#        return filter(match_tags, self.__stock_dictionary.values())
