# populator/helpers/formatpopulator.py
# Base classes for type-specific helpers for populating a DeviceTree.
#
# Copyright (C) 2009-2015  Red Hat, Inc.
#
# This copyrighted material is made available to anyone wishing to use,
# modify, copy, or redistribute it subject to the terms and conditions of
# the GNU Lesser General Public License v.2, or (at your option) any later
# version. This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY expressed or implied, including the implied
# warranties of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
# the GNU Lesser General Public License for more details.  You should have
# received a copy of the GNU Lesser General Public License along with this
# program; if not, write to the Free Software Foundation, Inc., 51 Franklin
# Street, Fifth Floor, Boston, MA 02110-1301, USA.  Any Red Hat trademarks
# that are incorporated in the source code or documentation are not subject
# to the GNU Lesser General Public License and may only be used or
# replicated with the express permission of Red Hat, Inc.
#
# Red Hat Author(s): David Lehman <dlehman@redhat.com>
#

from ... import formats
from ... import udev
from ...errors import FSError

from .populatorhelper import PopulatorHelper

import logging
log = logging.getLogger("blivet")


class FormatPopulator(PopulatorHelper):
    priority = 0
    _type_specifier = None

    def __init__(self, devicetree, data, device):
        """
            :param :class:`blivet.devicetree.DeviceTree` devicetree: the calling devicetree
            :param :class:`pyudev.Device` data: udev data describing a device
            :param device: device instance corresponding to the udev data
            :type device: :class:`~.devices.StorageDevice`
        """
        super().__init__(devicetree, data)
        self.device = device

    @classmethod
    def match(cls, data, device):  # pylint: disable=arguments-differ,unused-argument
        """ Return True if this helper is appropriate for the given device.

            :param :class:`pyudev.Device` data: udev data describing a device
            :param device: device instance corresponding to the udev data
            :type device: :class:`~.devices.StorageDevice`
            :returns: whether this class is appropriate for the specified device
            :rtype: bool
        """
        ret = False
        if cls is FormatPopulator:
            ret = True
        else:
            format_class = formats.get_device_format_class(cls._type_specifier)
            fmt_types = []
            if format_class is not None:
                fmt_types = format_class._udev_types[:]
                if cls._type_specifier and cls._type_specifier not in fmt_types:
                    fmt_types.append(cls._type_specifier)

            ret = (udev.device_get_format(data) in fmt_types)

        return ret

    def _get_kwargs(self):
        """ Return a kwargs dict to pass to DeviceFormat constructor. """
        kwargs = {"uuid": udev.device_get_uuid(self.data),
                  "label": udev.device_get_label(self.data),
                  "device": self.device.path,
                  "serial": udev.device_get_serial(self.data),
                  "exists": True}
        return kwargs

    def run(self):
        """ Create a format instance and associate it with the device instance. """
        kwargs = self._get_kwargs()
        if self._type_specifier is not None:
            type_spec = self._type_specifier
        else:
            type_spec = udev.device_get_format(self.data)

        try:
            log.info("type detected on '%s' is '%s'", self.device.name, type_spec)
            self.device.format = formats.get_format(type_spec, **kwargs)
        except FSError:
            log.warning("type '%s' on '%s' invalid, assuming no format",
                        type_spec, self.device.name)
            self.device.format = formats.DeviceFormat(device=self.device.path, exists=True)
            return

@@ -3281,142 +3281,42 @@
     
-def run(self):%0A        %22%22%22 Create a format instance and associate it with the device instance. %22%22%22%0A        kwargs = self._get_kwargs()
+@property%0A    def type_spec(self):
 %0A   
@@ -3473,17 +3473,225 @@
 lf.data)
-%0A
+ or None%0A%0A        return type_spec%0A%0A    def run(self):%0A        %22%22%22 Create a format instance and associate it with the device instance. %22%22%22%0A        kwargs = self._get_kwargs()%0A        type_spec = self.type_spec
 %0A       

Add a property indicating the type to pass to get_format.