import numpy as np
import pandas as pd
import pymc as pm

from sakkara.model.base import ModelComponent
from sakkara.relation.groupset import init


def build(df: pd.DataFrame, component: ModelComponent):
    """
    Build a complete PyMC model based on a single :class:`ModelComponent` (typically :class:`Likelihood`). Sakkara
    will trace all underlying components, and their respective groupings, necessary for creating the model.

    :param df: :class:`pandas.DataFrame` containing columns defining groups used among :class:`ModelComponent` objects.

    :param component: :class:`ModelComponent` object (of the lowest hierarchy, typically a :class:`Likelihood`) to init creation of PyMC model
        from.

    :return: A PyMC model generated by the dataframe and component.

    :rtype: :class:`pymc.Model`

    """
    tmp_df = df.copy()
    tmp_df.loc[:, 'global'] = 'global'
    tmp_df.loc[:, 'obs'] = np.arange(len(df))

    groups = component.retrieve_groups().union({'global', 'obs'})
    groupset = init(tmp_df.loc[:, list(groups)])

    with pm.Model(coords=groupset.coords()) as model:
        component.build(groupset)
    return model
