'''
Przechowywanie pojedynczego towaru w aplikacji Modny ciuch
Towar ma cenę, poziom zapasów i zestaw tagów
które można wykorzystać do zlokalizowania tego towaru.
'''


class StockItem(object):
    '''
    Towar magazynowy dla sklepu z odzieżą
    '''

    show_instrumentation = False

    min_price = 0.5 
    max_price = 500.0 

    max_stock_add = 50
    

    @staticmethod
    def get_tag_set_from_text(tag_string):
        '''
        Konwertuje listę rozdzielaną przecinkami na zbiór  
        pojedynczych pozycji
        Konwertuje tekst na wersję złożoną z małych liter i obcina 
        każde słowo
        '''
        # Usunięcie wiodących i końcowych spacji
        tag_string = str.strip(tag_string)

        if tag_string == '':
            return set()

        # Konwertuje ciąg znaków na małe litery
        tag_string = str.lower(tag_string)

        # Tworzy listę wszystkich słów w ciągu
        # rozdzieloną przecinkiem
        tag_list = str.split(tag_string, sep=',')

        # Usuwa wszystkie spacje na początku lub
        # końcu każdego ciągu na liście
        tag_list = map(str.strip,tag_list)

        # zwraca zestaw utworzony na podstawie listy

        result = set(tag_list)
        return result

    @staticmethod
    def get_text_from_tag_set(tag_set):
        tag_list = list(tag_set) 
        tag_list.sort()
        return ','.join(tag_list)
        
    @property
    def text_tags(self):
        '''
        Converts a set of items into a comma 
        separated text string for display or edit
        '''
        return StockItem.get_text_from_tag_set(self.tags) 

    @text_tags.setter
    def text_tags(self,tag_string):
        '''
        Konwertuje listę rozdzielaną przecinkami na zbiór  
        pojedynczych pozycji
        Konwertuje tekst na wersję złożoną z małych liter i obcina 
        każde słowo
        '''
        self.tags = StockItem.get_tag_set_from_text(tag_string)

    def __init__(self, stock_ref, price, tags):
        if StockItem.show_instrumentation:
            print('** Wywołano StockItem __init__')
        self.stock_ref = stock_ref
        self.__price = price
        self.__stock_level = 0
        self.StockItem_version = 1
        self.text_tags = tags

    def check_version(self):
        if StockItem.show_instrumentation:
            print('** Wywołano metodę check_version klasy StockItem')
        # To jest wersja 1 - nie trzeba niczego aktualizować 
        pass

    def __str__(self): 
        if StockItem.show_instrumentation:
            print('** Wywołano metodę __str__ klasy StockItem')
        template = '''Numer magazynowy: {0}
Cena: {1}
Poziom magazynowy: {2}
Znaczniki: {3}''' 

        return template.format(self.stock_ref, 
                               self.price, self.stock_level, 
                               self.text_tags)

    def add_stock(self,count):
        '''
        Dodaje stan magazynowy dla tego produktu. 
        Count zawiera ilość towaru do dodania
        Zgłasza wyjątek, jeśli liczba jest nieprawidłowa
        '''
        if StockItem.show_instrumentation:
            print('** Wywołano metodę add_stock klasy StockItem')
        if count < 0 or count > StockItem.max_stock_add:
            raise Exception('Nieprawidłowa ilość towaru')

        self.__stock_level = self.__stock_level + count

    def sell_stock(self, count):
        '''
        Sprzedaż towaru.
        count zawiera liczbę towaru do sprzedania
        Zgłasza wyjątek, jeśli liczba jest nieprawidłowa
        '''
        if StockItem.show_instrumentation:
            print('** Wywołano metodę sell_stock klasy StockItem')
        if count < 1:
            raise Exception('Nieprawidłowa ilość towaru do sprzedaży')

        if count > self.stock_level:
            raise Exception('W magazynie nie ma wystarczającej ilości towaru')

        self.__stock_level = self.__stock_level - count

    def set_price(self, new_price):
        if StockItem.show_instrumentation:
            print('** Wywołano metodę set_price klasy StockItem')
        if new_price < StockItem.min_price or new_price > StockItem.max_price:
            raise Exception('Cena poza zakresem')
        self.__price = new_price

    @property
    def price(self):
        if StockItem.show_instrumentation:
            print('** Wywołano metodę get price klasy StockItem')
        return self.__price

    @property
    def stock_level(self):
        if StockItem.show_instrumentation:
            print('** Wywołano metodę get stock_level klasy StockItem')
        return self.__stock_level


