# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
#      http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.

"""
Modules required to work with ironic_inspector:
    https://pypi.python.org/pypi/ironic-inspector
"""

import eventlet
from futurist import periodics
from oslo_config import cfg
from oslo_log import log as logging
from oslo_utils import importutils

from ironic.common import exception
from ironic.common.i18n import _
from ironic.common.i18n import _LE
from ironic.common.i18n import _LI
from ironic.common import keystone
from ironic.common import states
from ironic.conductor import task_manager
from ironic.drivers import base


LOG = logging.getLogger(__name__)


inspector_opts = [
    cfg.BoolOpt('enabled', default=False,
                help=_('whether to enable inspection using ironic-inspector')),
    cfg.StrOpt('service_url',
               help=_('ironic-inspector HTTP endpoint. If this is not set, '
                      'the ironic-inspector client default '
                      '(http://127.0.0.1:5050) will be used.')),
    cfg.IntOpt('status_check_period', default=60,
               help=_('period (in seconds) to check status of nodes '
                      'on inspection')),
]

CONF = cfg.CONF
CONF.register_opts(inspector_opts, group='inspector')
CONF.import_opt('auth_strategy', 'ironic.api.app')

client = importutils.try_import('ironic_inspector_client')


INSPECTOR_API_VERSION = (1, 0)


class Inspector(base.InspectInterface):
    """In-band inspection via ironic-inspector project."""

    @classmethod
    def create_if_enabled(cls, driver_name):
        """Create instance of Inspector if it's enabled.

        Reports log warning with given driver_name if it's not.

        :return: Inspector instance or None
        """
        if CONF.inspector.enabled:
            return cls()
        else:
            LOG.info(_LI("Inspection via ironic-inspector is disabled in "
                         "configuration for driver %s. To enable, change "
                         "[inspector] enabled = True."), driver_name)

    def __init__(self):
        if not CONF.inspector.enabled:
            raise exception.DriverLoadError(
                _('ironic-inspector support is disabled'))

        if not client:
            raise exception.DriverLoadError(
                _('python-ironic-inspector-client Python module not found'))

    def get_properties(self):
        """Return the properties of the interface.

        :returns: dictionary of <property name>:<property description> entries.
        """
        return {}  # no properties

    def validate(self, task):
        """Validate the driver-specific inspection information.

        If invalid, raises an exception; otherwise returns None.

        :param task: a task from TaskManager.
        """
        # NOTE(deva): this is not callable if inspector is disabled
        #             so don't raise an exception -- just pass.
        pass

    def inspect_hardware(self, task):
        """Inspect hardware to obtain the hardware properties.

        This particular implementation only starts inspection using
        ironic-inspector. Results will be checked in a periodic task.