import abc


class Phone:
    def __init__(self):
        self.color = None
        self.os = None
        self.screen_size = None
        self.processor = None
        self.device_name = None
        print('Built a new Phone!')

    def get_color(self):
        return self.color

    def set_color(self, color):
        self.color = color

    def get_os(self):
        return self.os

    def set_os(self, os_type):
        self.os = os_type

    def get_screen_size(self):
        return self.screen_size

    def set_screen_size(self, screen_size):
        self.screen_size = screen_size

    def get_processor(self):
        return self.processor

    def set_processor(self, processor):
        self.processor = processor

    def set_device_name(self, device_name):
        self.device_name = device_name

    def __str__(self):
        return f'A new {self.device_name} with: \n' \
               f'color={self.color}, \n' \
               f'OS = {self.os}, \n' \
               f'processor = {self.processor},\n' \
               f'screen-size = {self.screen_size}'


# the builder abstraction
class PhoneBuilder(metaclass=abc.ABCMeta):
    @abc.abstractmethod
    def start(self):
        pass

    @abc.abstractmethod
    def set_color(self, color):
        pass

    @abc.abstractmethod
    def get_result(self):
        pass

    @abc.abstractmethod
    def set_os(self):
        pass

    @abc.abstractmethod
    def set_processor(self):
        pass

    @abc.abstractmethod
    def set_screen_size(self):
        pass

    @abc.abstractmethod
    def set_device_name(self):
        pass


class PhoneBuilderApple(PhoneBuilder):
    def __init__(self):
        self.phone = None

    def start(self):
        self.phone = Phone()

    def set_color(self, color):
        self.phone.set_color(color)

    def set_os(self):
        self.phone.set_os('iOS')

    def set_screen_size(self):
        self.phone.set_screen_size('5.5')

    def set_processor(self):
        self.phone.set_processor('Mighty A11 Bionic')

    def set_device_name(self):
        self.phone.set_device_name('iPhone X')

    def get_result(self):
        return self.phone


class PhoneBuilderAndroid(PhoneBuilder):
    def __init__(self):
        self.phone = None

    def start(self):
        self.phone = Phone()

    def set_color(self, color):
        self.phone.color = color

    def set_os(self):
        self.phone.os = 'Android 8.0 Oreo'

    def set_screen_size(self):
        self.phone.screen_size = '6.0'

    def set_processor(self):
        self.phone.processor = 'Fantastic Snapdragon 835'

    def set_device_name(self):
        self.phone.device_name = 'Pixel 2 XL'

    def get_result(self):
        return self.phone


class PhoneBuildDirector:
    def __init__(self, phone_builder):
        self.phone_builder = phone_builder

    def construct(self):
        self.phone_builder.start()
        self.phone_builder.set_color('Black')
        self.phone_builder.set_os()
        self.phone_builder.set_screen_size()
        self.phone_builder.set_processor()
        self.phone_builder.set_device_name()
        return self.phone_builder.get_result()


if __name__ == '__main__':
    get_iphone = PhoneBuilderApple()
    print('------------------------------')
    get_pixel_xl = PhoneBuilderAndroid()
    print('------------------------------')
    phone_builder_director = PhoneBuildDirector(get_iphone)
    print('------------------------------')
    print(phone_builder_director.construct())
    print('------------------------------')
    phone_builder_director = PhoneBuildDirector(get_pixel_xl)
    print('------------------------------')
    print(phone_builder_director.construct())
