"""
Methods for rendering of the
various Jinja templates from the given data.
"""
import os
import json
import jinja2


def _read_template(filename):
    """
    Reads the template from the given filename.

    :param filename: path to the template file

    :return: template
    """
    with open(filename) as f:
        return jinja2.Template(f.read())


dropdown_template_file = os.path.abspath(os.path.join(
    os.path.dirname(__file__),
    'templates',
    'shared',
    'dropdown.json.j2'))

yaxes_template_file = os.path.abspath(os.path.join(
    os.path.dirname(__file__),
    'templates',
    'shared',
    'yaxes.json.j2'))

panel_template_file = file = os.path.abspath(os.path.join(
    os.path.dirname(__file__),
    'templates',
    'shared',
    'panel.json.j2'))

panel_target_template_file = os.path.abspath(os.path.join(
    os.path.dirname(__file__),
    'templates',
    'shared',
    'panel_target.json.j2'))

nren_dashboard_template_file = os.path.abspath(os.path.join(
    os.path.dirname(__file__),
    'templates',
    'nren_access',
    'nren-dashboard.json.j2'))

dashboard_template_file = os.path.abspath(os.path.join(
    os.path.dirname(__file__),
    'templates',
    'shared',
    'dashboard.json.j2'))


DROPDOWN_TEMPLATE = _read_template(dropdown_template_file)
YAXES_TEMPLATE = _read_template(yaxes_template_file)
PANEL_TEMPLATE = _read_template(panel_template_file)
PANEL_TARGET_TEMPLATE = _read_template(panel_target_template_file)
NREN_DASHBOARD_TEMPLATE = _read_template(nren_dashboard_template_file)
DASHBOARD_TEMPLATE = _read_template(dashboard_template_file)


def create_dropdown_panel(title, **kwargs):
    """
    Creates a dropdown panel from the given data.

    :param title: title of the dropdown panel
    :param kwargs: data to be used in the template

    :return: rendered dropdown panel JSON
    """

    return DROPDOWN_TEMPLATE.render({**kwargs, 'title': title})


def create_yaxes(type):
    """
    Creates the yaxes JSON for the given type, used in the panel template.

    :param type: type of yaxes to create (bits/s or errors/s)

    :return: rendered yaxes JSON
    """

    return YAXES_TEMPLATE.render({'type': type})


def create_panel_target(data):
    """
    Creates a panel target from the given data.
    A panel target defines how to query data for a single timeseries.

    :param data: data to be used in the template

    :return: rendered panel target JSON
    """

    return PANEL_TARGET_TEMPLATE.render(data)


def create_panel(data):
    """
    Creates a panel from the given data. Constructs the yaxes and panel targets
    and renders the panel template using these.

    :param data: data to be used in the template

    :return: rendered panel JSON
    """

    yaxes = create_yaxes(data.get('y_axis_type', 'bits'))
    targets = data.get('targets', [])
    for target in data.get('panel_targets', []):
        targets.append(create_panel_target(target))
    return PANEL_TEMPLATE.render({**data, 'yaxes': yaxes, 'targets': targets})


def render_dashboard(dashboard, nren=False):
    """
    Renders the dashboard template using the given data.
    NREN dashboards are rendered using a different template that uses
    a different layout than other dashboards.

    :param dashboard: data to be used in the template
    :param nren: whether the dashboard is an NREN dashboard

    :return: rendered dashboard JSON
    """

    if nren:
        template = NREN_DASHBOARD_TEMPLATE
    else:
        template = DASHBOARD_TEMPLATE

    rendered = template.render(dashboard)
    rendered = json.loads(rendered)
    rendered['uid'] = None
    rendered['id'] = None
    return rendered