# 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

import functools


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 = []

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

  return wrapper
