# -*- coding: UTF-8 -*-
#
#  Licensed to the Apache Software Foundation (ASF) under one
#  or more contributor license agreements.  See the NOTICE file
#  distributed with this work for additional information
#  regarding copyright ownership.  The ASF licenses this file
#  to you 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.

import os.path
from urlparse import urlsplit

from trac.config import BoolOption, ConfigSection, Option
from trac.core import Component, ComponentManager, ExtensionPoint, implements, \
                      ComponentMeta
from trac.db.api import TransactionContextManager, QueryContextManager, \
                        DatabaseManager
from trac.perm import IPermissionRequestor, PermissionSystem
from trac.util import get_pkginfo, lazy
from trac.util.compat import sha1
from trac.util.text import to_unicode, unicode_quote
from trac.versioncontrol import RepositoryManager
from trac.web.href import Href

from multiproduct.api import MultiProductSystem, ISupportMultiProductEnvironment
from multiproduct.cache import lru_cache, default_keymap
from multiproduct.config import Configuration
from multiproduct.dbcursor import BloodhoundConnectionWrapper, BloodhoundIterableCursor, \
                                  ProductEnvContextManager
from multiproduct.model import Product

import trac.env


class ComponentEnvironmentContext(object):
    def __init__(self, env, component):
        self._env = env
        self._component = component

    def __enter__(self):
        self._old_env = self._component.env
        self._env.component_activated(self._component)
        return self

    def __exit__(self, type, value, traceback):
        self._old_env.component_activated(self._component)


class Environment(trac.env.Environment):
    """Bloodhound environment manager

    This class is intended as monkey-patch replacement for
    trac.env.Environment. Required database access methods/properties
    are replaced to provide global view of the database in contrast
    to ProductEnvironment that features per-product view of the database
    (in the context of selected product).

        :param path:   the absolute path to the Trac environment
        :param create: if `True`, the environment is created and
                       populated with default data; otherwise, the
                       environment is expected to already exist.
        :param options: A list of `(section, name, value)` tuples that
                        define configuration options
    """

    multi_product_support_components = ExtensionPoint(ISupportMultiProductEnvironment)

    @property
    def global_setup_participants(self):
        """If multi product schema is enabled, return only setup participants
        that implement ISupportMultiProduct. Otherwise, all setup participants
        are considered global.
        """
        if self._multiproduct_schema_enabled:
            all_participants = self.setup_participants
            multiproduct_aware = set(self.multi_product_support_components)
            priority = lambda x: 0 if isinstance(x, MultiProductSystem) else 10

            return sorted(
                (c for c in all_participants if c in multiproduct_aware),
                key=priority
            )
        else:
            return self.setup_participants

    @property
    def product_setup_participants(self):
        """If multi product schema is enabled, return setup participants that
        need to be instantiated for each product env. Otherwise, return an
        empty list.
        """
        if self._multiproduct_schema_enabled:
            all_participants = self.setup_participants
            multiproduct_aware = set(self.multi_product_support_components)
            return [
                c for c in all_participants if c not in multiproduct_aware
            ]
        else:
            return []

    def __init__(self, path, create=False, options=[]):
        # global environment w/o parent, set these two before super.__init__
        # as database access can take place within trac.env.Environment
        self.parent = None
        self.product = None

        # `trac.env.Environment.__init__` is not invoked as creation is handled differently
        # from base implementation - different setup participants are invoked when creating
        # global environment.
        ComponentManager.__init__(self)

        self.path = path
        self.systeminfo = []
        self._href = self._abs_href = None

        self._multiproduct_schema_enabled = False

        if create:
            self.create(options)
        else:
            self.verify()
            self.setup_config()

        # invoke `IEnvironmentSetupParticipant.environment_created` for all
        # global setup participants
        if create:
            for participant in self.global_setup_participants:
                with ComponentEnvironmentContext(self, participant):
                    participant.environment_created()

    @property
    def db_query(self):
        return ProductEnvContextManager(super(Environment, self).db_query, self) \
            if self._multiproduct_schema_enabled else self.db_direct_query

    @property
    def db_transaction(self):
        return ProductEnvContextManager(super(Environment, self).db_transaction, self) \
            if self._multiproduct_schema_enabled else self.db_direct_transaction

    @property
    def db_direct_query(self):
        return ProductEnvContextManager(super(Environment, self).db_query)

    @property
    def db_direct_transaction(self):
        return ProductEnvContextManager(super(Environment, self).db_transaction)

    def all_product_envs(self):
        return [ProductEnvironment(self, product) for product in Product.select(self)]

    def needs_upgrade(self):
        """Return whether the environment needs to be upgraded."""
        def needs_upgrade_in_env(participant, env):
            with ComponentEnvironmentContext(env, participant):
                with env.db_query as db:
                    if participant.environment_needs_upgrade(db):
                        self.log.warn("component %s.%s requires environment upgrade in environment %s...",
                                      participant.__module__, participant.__class__.__name__,
                                      env)
                        return True
        if any(needs_upgrade_in_env(participant, self)
               for participant in self.global_setup_participants):
            return True

        # until schema is multi product aware, product environments can't (and shouldn't) be
        # instantiated
        if self._multiproduct_schema_enabled:
            if any(needs_upgrade_in_env(participant, env)
                   for env in [self] + self.all_product_envs()
                   for participant in self.product_setup_participants):
                return True
        return False

    def upgrade(self, backup=False, backup_dest=None):
        """Upgrade database.

        :param backup: whether or not to backup before upgrading
        :param backup_dest: name of the backup file
        :return: whether the upgrade was performed
        """
        def upgrader_for_env(participant, env):
            with ComponentEnvironmentContext(env, participant):
                with env.db_query as db:
                    if participant.environment_needs_upgrade(db):
                        self.log.info(
                            "%s.%s needs upgrade in environment %s...",
                            participant.__module__,
                            participant.__class__.__name__,
                            env)
                        return env, participant

        def upgraders_for_product_envs():
            upgraders = (upgrader_for_env(participant, env)
                         for participant in self.product_setup_participants
                         for env in [self] + self.all_product_envs())
            return [u for u in upgraders if u]

        # first enumerate components that are multi product aware and
        # require upgrade in global environment
        global_upgraders = [upgrader_for_env(participant, self)
                            for participant in self.global_setup_participants]
        global_upgraders = [u for u in global_upgraders if u]
        product_upgraders = None
        if not global_upgraders and self._multiproduct_schema_enabled:
            # if no upgrades required in global environment, enumerate
            # required upgrades for product environments
            product_upgraders = upgraders_for_product_envs()

        if not global_upgraders + (product_upgraders or []):
            return False

        if backup:
            try:
                self.backup(backup_dest)
            except Exception, e:
                raise trac.env.BackupError(e)

        def execute_upgrades(upgraders_list):
            for env, participant in upgraders_list:
                self.log.info("%s.%s upgrading in environment %s...",
                              participant.__module__,
                              participant.__class__.__name__,
                              env)
                with ComponentEnvironmentContext(env, participant):
                    with env.db_transaction as db:
                        participant.upgrade_environment(db)
                # Database schema may have changed, so close all connections
                DatabaseManager(env).shutdown()

        # execute global upgrades first, product environment upgrades next
        execute_upgrades(global_upgraders)
        if product_upgraders is None and self._multiproduct_schema_enabled:
            product_upgraders = upgraders_for_product_envs()
        if product_upgraders:
            execute_upgrades(product_upgraders)
        return True

    def get_version(self, db=None, initial=False):
        """Return the current version of the database.  If the
        optional argument `initial` is set to `True`, the version of
        the database used at the time of creation will be returned.
        """
        rows = self.db_direct_query("""
                SELECT value FROM system WHERE name='%sdatabase_version'
                """ % ('initial_' if initial else ''))
        return (rows and int(rows[0][0])) or 0

    def enable_multiproduct_schema(self, enable=True):
        self._multiproduct_schema_enabled = enable
        BloodhoundIterableCursor.cache_reset()

# replace trac.env.Environment with Environment
trac.env.Environment = Environment


# this must follow the monkey patch (trac.env.Environment) above, otherwise
# trac.test.EnvironmentStub will not be correct as the class will derive from
# not replaced trac.env.Environment
import trac.test

class EnvironmentStub(trac.test.EnvironmentStub):
    """Bloodhound test environment stub

    This class replaces trac.test.EnvironmentStub and extends it with parent
    and product properties (same case as with the Environment).
    """
    def __init__(self, default_data=False, enable=None, disable=None,
                 path=None, destroying=False):
        self.parent = None
        self.product = None

        self._multiproduct_schema_enabled = False

        super(EnvironmentStub, self).__init__(default_data=False,
                                              enable=enable, disable=disable,
                                              path=path, destroying=destroying)
        if default_data:
            self.reset_db(default_data)

    @staticmethod
    def enable_component_in_config(env, cls):
        """Keep track of enabled state in configuration as well
        during test runs. This is closer to reality than
        inherited `enable_component` method.
        """
        env.config['components'].set(env._component_name(cls), 'enabled')
        env.enabled.clear()
        env.components.pop(cls, None)
        try:
            del env._rules
        except AttributeError:
            pass
        # FIXME: Shall we ?
        #env.config.save()

    @staticmethod
    def disable_component_in_config(env, component):
        """Keep track of disabled state in configuration as well
        during test runs. This is closer to reality than
        inherited `disable_component` method.
        """
        if isinstance(component, type):
            cls = component
        else:
            cls = component.__class__
        env.config['components'].set(env._component_name(cls), 'disabled')
        env.enabled.clear()
        env.components.pop(cls, None)
        try:
            del env._rules
        except AttributeError:
            pass
        env.config.save()

    def reset_db(self, default_data=None):
        multiproduct_schema = self._multiproduct_schema_enabled
        self._multiproduct_schema_enabled = False
        try:
            super(EnvironmentStub, self).reset_db(default_data=default_data)
        finally:
            self._multiproduct_schema_enabled = multiproduct_schema

# replace trac.test.EnvironmentStub
trac.test.EnvironmentStub = EnvironmentStub


class ProductEnvironment(Component, ComponentManager):
    """Bloodhound product-aware environment manager.

    Bloodhound encapsulates access to product resources stored inside a
    Trac environment via product environments. They are compatible lightweight
    irepresentations of top level environment.

    Product environments contain among other things:

    * configuration key-value pairs stored in the database,
    * product-aware clones of the wiki and ticket attachments files,

    Product environments do not have:

    * product-specific templates and plugins,
    * a separate database
    * active participation in database upgrades and other setup tasks

    See https://issues.apache.org/bloodhound/wiki/Proposals/BEP-0003
    """

    class __metaclass__(ComponentMeta):

        def select_global_env(f):
            """Replaces env with env.parent where appropriate"""
            # Keep the signature of __call__ method
            def __call__(self, env, *args, **kwargs):
                g_env = env.parent if isinstance(env,
                                                 ProductEnvironment) else env
                return f(self, g_env, *args, **kwargs)
            __call__.clear = f.clear

            return __call__

        def product_env_keymap(args, kwds, kwd_mark):
            # Remove meta-reference to self (i.e. product env class)
            args = args[1:]
            try:
                product = kwds['product']
            except KeyError:
                # Product provided as positional argument
                if isinstance(args[1], Product):
                    args = (args[0], args[1].prefix) + args[2:]
            else:
                # Product supplied as keyword argument
                if isinstance(product, Product):
                    kwds['product'] = product.prefix
            return default_keymap(args, kwds, kwd_mark)

        @select_global_env
        @lru_cache(maxsize=100, keymap=product_env_keymap)
        def __call__(self, *args, **kwargs):
            """Return an existing instance if there is a hit
            in the global LRU cache, otherwise create a new instance.
            """
            return ComponentMeta.__call__(self, *args, **kwargs)

        del product_env_keymap, select_global_env

    implements(trac.env.ISystemInfoProvider, IPermissionRequestor)

    setup_participants = ExtensionPoint(trac.env.IEnvironmentSetupParticipant)
    multi_product_support_components = ExtensionPoint(ISupportMultiProductEnvironment)

    @classmethod
    def clear_env_cache(cls):
        cls.__metaclass__.__call__.clear()

    @property
    def product_setup_participants(self):
        return [
            component for component in self.setup_participants
            if component not in self.multi_product_support_components
        ]

    components_section = ConfigSection('components',
        """This section is used to enable or disable components
        provided by plugins, as well as by Trac itself.

        See also: TracIni , TracPlugins
        """)

    @property
    def shared_plugins_dir():
        """Product environments may not add plugins.
        """
        return ''

    _base_url = Option('trac', 'base_url', '',
        """Reference URL for the Trac deployment.

        This is the base URL that will be used when producing
        documents that will be used outside of the web browsing
        context, like for example when inserting URLs pointing to Trac
        resources in notification e-mails.""", doc_domain='multiproduct')

    @property
    def base_url(self):
        base_url = self._base_url
        if base_url == self.parent.base_url:
            return ''
        return base_url

    _base_url_for_redirect = BoolOption('trac', 'use_base_url_for_redirect',
            False,
        """Optionally use `[trac] base_url` for redirects.

        In some configurations, usually involving running Trac behind
        a HTTP proxy, Trac can't automatically reconstruct the URL
        that is used to access it. You may need to use this option to
        force Trac to use the `base_url` setting also for
        redirects. This introduces the obvious limitation that this
        environment will only be usable when accessible from that URL,
        as redirects are frequently used. ''(since 0.10.5)''""",
                                        doc_domain='multiproduct')

    @property
    def project_name(self):
        """Name of the product.
        """
        return self.product.name

    @property
    def project_description(self):
        """Short description of the product.
        """
        return self.product.description

    @property
    def project_url(self):
        """URL of the main project web site, usually the website in
        which the `base_url` resides. This is used in notification
        e-mails.
        """
        # FIXME: Should products have different values i.e. config option ?
        return self.parent.project_url

    project_admin = Option('project', 'admin', '',
        """E-Mail address of the product's leader / administrator.""",
                           doc_domain='multiproduct')

    @property
    def project_footer(self):
        """Page footer text (right-aligned).
        """
        # FIXME: Should products have different values i.e. config option ?
        return self.parent.project_footer

    project_icon = Option('project', 'icon', 'common/trac.ico',
        """URL of the icon of the product.""", doc_domain='multiproduct')

    log_type = Option('logging', 'log_type', 'inherit',
        """Logging facility to use.

        Should be one of (`inherit`, `none`, `file`, `stderr`,
        `syslog`, `winlog`).""", doc_domain='multiproduct')

    log_file = Option('logging', 'log_file', 'trac.log',
        """If `log_type` is `file`, this should be a path to the
        log-file.  Relative paths are resolved relative to the `log`
        directory of the environment.""", doc_domain='multiproduct')

    log_level = Option('logging', 'log_level', 'DEBUG',
        """Level of verbosity in log.

        Should be one of (`CRITICAL`, `ERROR`, `WARN`, `INFO`, `DEBUG`).""",
                       doc_domain='multiproduct')

    log_format = Option('logging', 'log_format', None,
        """Custom logging format.

        If nothing is set, the following will be used:

        Trac[$(module)s] $(levelname)s: $(message)s

        In addition to regular key names supported by the Python
        logger library (see
        http://docs.python.org/library/logging.html), one could use:

        - $(path)s     the path for the current environment
        - $(basename)s the last path component of the current environment
        - $(project)s  the project name

        Note the usage of `$(...)s` instead of `%(...)s` as the latter form
        would be interpreted by the ConfigParser itself.

        Example:
        `($(thread)d) Trac[$(basename)s:$(module)s] $(levelname)s: $(message)s`

        ''(since 0.10.5)''""", doc_domain='multiproduct')

    def __init__(self, env, product, create=False):
        """Initialize the product environment.

        :param env:     the global Trac environment
        :param product: product prefix or an instance of
                        multiproduct.model.Product
        """
        if not isinstance(env, trac.env.Environment):
            cls = self.__class__
            raise TypeError("Initializer must be called with " \
                "trac.env.Environment instance as first argument " \
                "(got %s instance instead)" %
                         (cls.__module__ + '.' + cls.__name__, ))

        ComponentManager.__init__(self)

        if isinstance(product, Product):
            if product._env is not env:
                raise ValueError("Product's environment mismatch")
        elif isinstance(product, basestring):
            products = Product.select(env, where={'prefix': product})
            if len(products) == 1 :
                product = products[0]
            else:
                env.log.debug("Products for '%s' : %s",
                              product, products)
                raise LookupError("Missing product %s" % (product,))

        self.parent = env
        self.product = product
        self.systeminfo = []

        self.setup_config()

        # when creating product environment, invoke `IEnvironmentSetupParticipant.environment_created`
        # for all setup participants that don't support multi product environments
        if create:
            for participant in self.product_setup_participants:
                with ComponentEnvironmentContext(self, participant):
                    participant.environment_created()

    def __getitem__(self, cls):
        if issubclass(cls, trac.env.Environment):
            return self.parent
        elif cls is self.__class__:
            return self
        else:
            return ComponentManager.__getitem__(self, cls)

    def __getattr__(self, attrnm):
        """Forward attribute access request to parent environment.

        Initially this will affect the following members of
        `trac.env.Environment` class:

        system_info_providers, secure_cookies, project_admin_trac_url,
        get_system_info, get_version, get_templates_dir, get_templates_dir,
        get_log_dir, backup
        """
        try:
            if attrnm in ('parent', '_rules'):
                raise AttributeError
            return getattr(self.parent, attrnm)
        except AttributeError:
            raise AttributeError("'%s' object has no attribute '%s'" %
                    (self.__class__.__name__, attrnm))

    def __repr__(self):
        return "<%s %s at %s>" % (self.__class__.__name__,
                                 repr(self.product.prefix),
                                 hex(id(self)))

    @lazy
    def path(self):
        """The subfolder `./products/<product prefix>` relative to the
        top-level directory of the global environment will be the root of
        product file system area.
        """
        folder = os.path.join(self.parent.path, 'products', self.product.prefix)
        if not os.path.exists(folder):
            os.makedirs(folder)
        return folder

    # IPermissionRequestor methods
    def get_permission_actions(self):
        """Implement the product-specific `PRODUCT_ADMIN` meta permission.
        """
        actions = set()
        permsys = PermissionSystem(self)
        for requestor in permsys.requestors:
            if requestor is not self and requestor is not permsys:
                for action in requestor.get_permission_actions() or []:
                    if isinstance(action, tuple):
                        actions.add(action[0])
                    else:
                        actions.add(action)
        # PermissionSystem's method was not invoked
        actions.add('EMAIL_VIEW')
        # FIXME: should not be needed, JIC better double check
        actions.discard('TRAC_ADMIN')
        return [('PRODUCT_ADMIN', list(actions))]

    # ISystemInfoProvider methods

    # Same as parent environment's . Avoid duplicated code
    component_activated = trac.env.Environment.component_activated.im_func
    _component_name = trac.env.Environment._component_name.im_func
    _component_rules = trac.env.Environment._component_rules
    enable_component = trac.env.Environment.enable_component.im_func
    get_known_users = trac.env.Environment.get_known_users.im_func
    get_repository = trac.env.Environment.get_repository.im_func

    is_component_enabled_local = trac.env.Environment.is_component_enabled.im_func

    def is_enabled(self, cls):
        """Return whether the given component class is enabled."""
        modtime = max(self.config.get_lock_file_mtime(),
                      self.config._lastmtime)
        if modtime > self._config_mtime:
            self.enabled.clear()
            try:
                del self._rules
            except AttributeError:
                pass
            # FIXME : Improve cache hits by tracking global env last mtime
            self.parent.enabled.clear()
            try:
                del self.parent._rules
            except AttributeError:
                pass
        self._config_mtime = modtime
        return super(ProductEnvironment, self).is_enabled(cls)

    def is_component_enabled(self, cls):
        """Implemented to only allow activation of components already
        activated in the global environment that are in turn not disabled in
        the configuration.

        This is called by the `ComponentManager` base class when a
        component is about to be activated. If this method returns
        `False`, the component does not get activated. If it returns
        `None`, the component only gets activated if it is located in
        the `plugins` directory of the environment.
        """
        if cls is self.__class__:
            # Prevent lookups in parent env ... will always fail
            return True
        # FIXME : Maybe checking for ComponentManager is too drastic
        elif issubclass(cls, ComponentManager):
            # Avoid clashes with overridden Environment's options
            return False
        elif self.parent[cls] is None:
            return False
        return self.is_component_enabled_local(cls)

    def get_db_cnx(self):
        """Return a database connection from the connection pool

        :deprecated: Use :meth:`db_transaction` or :meth:`db_query` instead

        `db_transaction` for obtaining the `db` database connection
        which can be used for performing any query
        (SELECT/INSERT/UPDATE/DELETE)::

           with env.db_transaction as db:
               ...


        `db_query` for obtaining a `db` database connection which can
        be used for performing SELECT queries only::

           with env.db_query as db:
               ...
        """
        return BloodhoundConnectionWrapper(self.parent.get_db_cnx(), self)

    @property
    def db_exc(self):
        """Return an object (typically a module) containing all the
        backend-specific exception types as attributes, named
        according to the Python Database API
        (http://www.python.org/dev/peps/pep-0249/).

        To catch a database exception, use the following pattern::

            try:
                with env.db_transaction as db:
                    ...
            except env.db_exc.IntegrityError, e:
                ...
        """
        # exception types same as in global environment
        return self.parent.db_exc

    def with_transaction(self, db=None):
        """Decorator for transaction functions :deprecated:
        """
        raise NotImplementedError('Deprecated method')

    def get_read_db(self):
        """Return a database connection for read purposes :deprecated:

        See `trac.db.api.get_read_db` for detailed documentation.
        """
        return BloodhoundConnectionWrapper(self.parent.get_read_db(), self)

    @property
    def db_query(self):
        """Return a context manager which can be used to obtain a
        read-only database connection.

        Example::

            with env.db_query as db:
                cursor = db.cursor()
                cursor.execute("SELECT ...")
                for row in cursor.fetchall():
                    ...

        Note that a connection retrieved this way can be "called"
        directly in order to execute a query::

            with env.db_query as db:
                for row in db("SELECT ..."):
                    ...

        If you don't need to manipulate the connection itself, this
        can even be simplified to::

            for row in env.db_query("SELECT ..."):
                ...

        :warning: after a `with env.db_query as db` block, though the
          `db` variable is still available, you shouldn't use it as it
          might have been closed when exiting the context, if this
          context was the outermost context (`db_query` or
          `db_transaction`).
        """
        return ProductEnvContextManager(QueryContextManager(self.parent), self)

    @property
    def db_transaction(self):
        """Return a context manager which can be used to obtain a
        writable database connection.

        Example::

            with env.db_transaction as db:
                cursor = db.cursor()
                cursor.execute("UPDATE ...")

        Upon successful exit of the context, the context manager will
        commit the transaction. In case of nested contexts, only the
        outermost context performs a commit. However, should an
        exception happen, any context manager will perform a rollback.

        Like for its read-only counterpart, you can directly execute a
        DML query on the `db`::

            with env.db_transaction as db:
                db("UPDATE ...")

        If you don't need to manipulate the connection itself, this
        can also be simplified to::

            env.db_transaction("UPDATE ...")

        :warning: after a `with env.db_transaction` as db` block,
          though the `db` variable is still available, you shouldn't
          use it as it might have been closed when exiting the
          context, if this context was the outermost context
          (`db_query` or `db_transaction`).
        """
        return ProductEnvContextManager(TransactionContextManager(self.parent), self)

    def shutdown(self, tid=None):
        """Close the environment."""
        RepositoryManager(self).shutdown(tid)
        # FIXME: Shared DB so IMO this should not happen ... at least not here
        #DatabaseManager(self).shutdown(tid)
        if tid is None:
            self.log.removeHandler(self._log_handler)
            self._log_handler.flush()
            self._log_handler.close()
            del self._log_handler

    def create(self, options=[]):
        """Placeholder for compatibility when trying to create the basic
        directory structure of the environment, etc ...

        This method does nothing at all.
        """
        # TODO: Handle options args

    def setup_config(self):
        """Load the configuration object.
        """
        import trac.config

        parent_path = MultiProductSystem(self.parent).product_config_parent
        if parent_path and os.path.isfile(parent_path):
            parents = [trac.config.Configuration(parent_path)]
        else:
            parents = [self.parent.config]
        self.config = Configuration(self.parent, self.product.prefix, parents)
        self._config_mtime = 0
        self.setup_log()

    def setup_log(self):
        """Initialize the logging sub-system."""
        from trac.log import logger_handler_factory
        logtype = self.log_type
        logfile = self.log_file
        format = self.log_format

        self.parent.log.debug("Log type '%s' for product '%s'",
                logtype, self.product.prefix)

        # Force logger inheritance on identical configuration
        if (logtype, logfile, format) == (self.parent.log_type,
                self.parent.log_file, self.parent.log_format):
            logtype = 'inherit'

        if logtype == 'inherit':
            self.log = self.parent.log
            self._log_handler = self.parent._log_handler
            self.parent.log.info("Inheriting parent logger for product '%s'",
                    self.product.prefix)
        else:
            if logtype == 'file' and not os.path.isabs(logfile):
                logfile = os.path.join(self.get_log_dir(), logfile)
            logid = 'Trac.%s.%s' % \
                    (sha1(self.parent.path).hexdigest(), self.product.prefix)
            if format:
                format = format.replace('$(', '%(') \
                         .replace('%(path)s', self.path) \
                         .replace('%(basename)s', os.path.basename(self.path)) \
                         .replace('%(project)s', self.project_name)
            self.log, self._log_handler = logger_handler_factory(
                logtype, logfile, self.log_level, logid, format=format)

        from trac import core, __version__ as VERSION
        self.log.info('-' * 32 +
                        ' product %s environment startup [Trac %s] ' +
                        '-' * 32,
                      self.product.prefix,
                      get_pkginfo(core).get('version', VERSION))

    def needs_upgrade(self):
        """Return whether the environment needs to be upgraded."""
        # Upgrades are handled by global environment
        return False

    def upgrade(self, backup=False, backup_dest=None):
        """Upgrade database.

        :param backup: whether or not to backup before upgrading
        :param backup_dest: name of the backup file
        :return: whether the upgrade was performed
        """
        # Upgrades handled by global environment
        return True

    @lazy
    def href(self):
        """The application root path"""
        return Href(urlsplit(self.abs_href.base).path)

    @lazy
    def abs_href(self):
        """The application URL"""
        if not self.base_url:
            urlpattern = MultiProductSystem(self.parent).product_base_url
            if not urlpattern:
                self.log.warn("product_base_url option not set in "
                              "configuration, generated links may be "
                              "incorrect")
                urlpattern = 'products/$(prefix)s'
            envname = os.path.basename(self.parent.path)
            prefix = unicode_quote(self.product.prefix, safe="")
            name = unicode_quote(self.product.name, safe="")
            url = urlpattern.replace('$(', '%(') \
                            .replace('%(envname)s', envname) \
                            .replace('%(prefix)s', prefix) \
                            .replace('%(name)s', name)
            if urlsplit(url).netloc:
                #  Absolute URLs
                _abs_href = Href(url)
            else:
                # Relative URLs
                parent_href = Href(self.parent.abs_href(),
                                   path_safe="/!~*'()%",
                                   query_safe="!~*'()%")
                _abs_href = Href(parent_href(url))
        else:
            _abs_href = Href(self.base_url)
        return _abs_href

    # Multi-product API extensions

    @classmethod
    def lookup_global_env(cls, env):
        return env.parent if isinstance(env, ProductEnvironment) else env

    @classmethod
    def lookup_env(cls, env, prefix=None, name=None):
        """Instantiate environment according to product prefix or name

        @throws LookupError if no product matches neither prefix nor name
        """
        if isinstance(env, ProductEnvironment):
            global_env = env.parent
        else:
            global_env = env

        # FIXME: Update if multiproduct.dbcursor.GLOBAL_PRODUCT != ''
        if not prefix and not name:
            return global_env
        elif isinstance(env, ProductEnvironment) and \
                env.product.prefix == prefix:
            return env
        if prefix:
            try:
                return ProductEnvironment(global_env, prefix)
            except LookupError:
                if not name:
                    raise
        if name:
            # Lookup product by name
            products = Product.select(global_env, where={'name' : name})
            if products:
                return ProductEnvironment(global_env, products[0])
            else:
                raise LookupError("Missing product '%s'" % (name,))
        else:
            raise LookupError("Mising product '%s'" % (prefix or name,))

    @classmethod
    def resolve_href(cls, to_env, at_env):
        """Choose absolute or relative href when generating links to
        a product (or global) environment.

        @param at_env:        href expansion is taking place in the
                              scope of this environment
        @param to_env:        generated URLs point to resources in
                              this environment
        """
        at_href = at_env.abs_href()
        target_href = to_env.abs_href()
        if urlsplit(at_href)[1] == urlsplit(target_href)[1]:
            return to_env.href
        else:
            return to_env.abs_href


lookup_product_env = ProductEnvironment.lookup_env
resolve_product_href = ProductEnvironment.resolve_href

# Override product-specific options
from multiproduct.config import ProductPermissionPolicyOption
PermissionSystem.policies.__class__ = ProductPermissionPolicyOption
