# Copyright 2015 The Chromium OS Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.

"""Abstract ObjectFactory class used for injection of external dependencies."""

from __future__ import print_function

class ObjectFactoryIllegalOperation(Exception):
  """Raised when attemping an illegal ObjectFactory operation."""

_NO_SINGLETON_INSTANCE = object()

class ObjectFactory(object):
  """Abstract object factory, used for injection of external dependencies.

  A call to Setup(...) is necessary before a call to GetInstance().
  """

  _object_name = ''
  _is_setup = False
  _setup_type = None
  _setup_instance = None
  _types = {}

  def __init__(self, object_name, setup_types, allowed_transitions=None):
    """ObjectFactory constructor.

    Args:
      object_name: Human readable name for the type of object that this factory
                   generates.
      setup_types: A (set up type name -> generator function) dictionary, which
                   teaches ObjectFactory how to construct instances after setup
                   has been called. For set up types where a singleton instance
                   is specified at setup(...) time, generator function should be
                   None.
      allowed_transitions: Optional function, where
                           allowed_transitions(from_type, to_type) specifies
                           whether transition from |from_type| to |to_type| is
                           allowed.

                           If unspecified, no transitions are allowed.
    """

    self._object_name = object_name
    self._types = setup_types
    self._allowed_transitions = allowed_transitions

  def Setup(self, setup_type, singleton_instance=_NO_SINGLETON_INSTANCE):
    # Prevent set up to unknown types.
    if setup_type not in self._types:
      raise ObjectFactoryIllegalOperation(
          'Unknown %s setup_type %s' % (self._object_name, setup_type))

    # Prevent illegal setup transitions.
    if self._is_setup:
      if self._allowed_transitions:
        if not self._allowed_transitions(self._setup_type, setup_type):
          raise ObjectFactoryIllegalOperation(
              'Illegal set up transition from %s to %s.' % (self._setup_type,
                                                            setup_type))
      else:
        raise ObjectFactoryIllegalOperation(
            '%s already set up.' % self._object_name)

    # Allow singleton_instance if and only if factory method for this type is
    # None.
    instance_supplied = (singleton_instance != _NO_SINGLETON_INSTANCE)
    factory_is_none = (self._types[setup_type] is None)
    if instance_supplied != factory_is_none:
      raise ObjectFactoryIllegalOperation(
          'singleton_instance should be supplied if and only if setup_type has '
          'a factory that is None.')

    self._setup_type = setup_type
    self._setup_instance = singleton_instance
    self._is_setup = True

  @property
  def is_setup(self):
    """Returns True iff a call to get_instance is expected to succeed."""
    return self._is_setup

  @property
  def setup_type(self):
    """Returns the setup_type."""
    return self._setup_type

  def GetInstance(self):
    """Returns an object instance iff setup has been called.

    Raises:
      ObjectFactoryIllegalOperation: if setup has not yet been called.
    """
    if not self.is_setup:
      raise ObjectFactoryIllegalOperation(
          '%s is not set up.' % self._object_name)
    if self._setup_instance != _NO_SINGLETON_INSTANCE:
      return self._setup_instance
    return self._types[self.setup_type]()

  def _clear_setup(self):
    """Clear setup, for testing purposes only."""
    self._setup_type = None
    self._is_setup = False
    self._setup_instance = _NO_SINGLETON_INSTANCE


def CachedFunctionCall(function):
  """Wraps a parameterless |function| in a cache."""
  cached_value = []

  def wrapper():
    if not cached_value:
      cached_value.append(function())
    return cached_value[0]

  return wrapper
