# -*- coding: utf-8 -*-

"""

Components Builder
==================

Build the components at the build of a registry.

"""
import odoo
from odoo import api, models
from .core import (
_component_databases,
ComponentRegistry,
DEFAULT_CACHE_SIZE,
)

[docs]class ComponentBuilder(models.AbstractModel):
""" Build the component classes

And register them in a global registry.

Every time an Odoo registry is built, the know components are cleared and
rebuilt as well.  The Component classes are built using the same mechanism
than Odoo's Models: a final class is created, taking every Components with
a _name and applying Components with an _inherits upon them.

The final Component classes are registered in global registry.

This class is an Odoo model, allowing us to hook the build of the
_register_hook. This method is called after all modules are loaded, so
we are sure that we have all the components Classes and in the correct
order.

"""
_name = 'component.builder'
_description = 'Component Builder'

_components_registry_cache_size = DEFAULT_CACHE_SIZE

@api.model_cr
def _register_hook(self):
# This method is called by Odoo when the registry is built,
# so in case the registry is rebuilt (cache invalidation, ...),
# we have to to rebuild the components. We use a new
# registry so we have an empty cache and we'll add components in it.
components_registry = self._init_global_registry()
self.build_registry(components_registry)

def _init_global_registry(self):
components_registry = ComponentRegistry(
cachesize=self._components_registry_cache_size
)
_component_databases[self.env.cr.dbname] = components_registry
return components_registry

[docs]    def build_registry(self, components_registry, states=None,
if not states:
# lookup all the installed (or about to be) addons and generate
# the graph, so we can load the components following the order
graph = odoo.modules.graph.Graph()

query = (
"SELECT name "
"FROM ir_module_module "
"WHERE state IN %s "
)
params = [tuple(states)]
query += " AND name NOT IN %s "
self.env.cr.execute(query, params)

module_list = [name for (name,) in self.env.cr.fetchall()
if name not in graph]

for module in graph:
components_registry=components_registry)

""" Build every component known by MetaComponent for an odoo module

The final component (composed by all the Component classes in this
module) will be pushed into the registry.

:param module: the name of the addon for which we want to load
the components
:type module: str | unicode
:param registry: the registry in which we want to put the Component
:type registry: :py:class:~.core.ComponentRegistry
"""
components_registry = (
components_registry or
_component_databases[self.env.cr.dbname])