# -*- coding: utf-8 -*-
'''
Manage Grafana v3.0 Dashboards

.. versionadded:: 2016.3.0

.. code-block:: yaml

    grafana:
      grafana_timeout: 3
      grafana_token: qwertyuiop
      grafana_url: 'https://url.com'

.. code-block:: yaml

    Ensure minimum dashboard is managed:
      grafana_dashboard.present:
        - name: insightful-dashboard
        - base_dashboards_from_pillar:
          - default_dashboard
        - base_rows_from_pillar:
          - default_row
        - base_panels_from_pillar:
          - default_panel
        - dashboard:
            rows:
              - title: Usage
                panels:
                  - targets:
                      - target: alias(constantLine(50), 'max')
                    title: Imaginary
                    type: graph


The behavior of this module is to create dashboards if they do not exist, to
add rows if they do not exist in existing dashboards, and to update rows if
they exist in dashboards. The module will not manage rows that are not defined,
allowing users to manage their own custom rows.
'''

# Import Python libs
from __future__ import absolute_import
import copy
import json
import requests

# Import Salt libs
import salt.ext.six as six
from salt.utils.dictdiffer import DictDiffer


def __virtual__():
    '''Only load if grafana v2.0 is configured.'''
    return __salt__['config.get']('grafana_version', 1) == 3


_DEFAULT_DASHBOARD_PILLAR = 'grafana_dashboards:default'
_DEFAULT_PANEL_PILLAR = 'grafana_panels:default'
_DEFAULT_ROW_PILLAR = 'grafana_rows:default'
_PINNED_ROWS_PILLAR = 'grafana_pinned_rows'


def present(name,
            base_dashboards_from_pillar=None,
            base_panels_from_pillar=None,
            base_rows_from_pillar=None,
            dashboard=None,
            dashboard_format='yaml',
            profile='grafana'):
    '''
    Ensure the grafana dashboard exists and is managed.

    name
        Name of the grafana dashboard.

    base_dashboards_from_pillar
        A pillar key that contains a list of dashboards to inherit from

    base_panels_from_pillar
        A pillar key that contains a list of panels to inherit from

    base_rows_from_pillar
        A pillar key that contains a list of rows to inherit from

    dashboard
        A dict that defines a dashboard that should be managed.

    dashboard_format
        You can use two formats for dashboards. You can use the JSON format
        if you provide a complete dashboard in raw JSON or you can use the YAML
        format (this is the default) and provide a description of the
        dashboard in YAML.

    profile
        A pillar key or dict that contains grafana information
    '''
    ret = {'name': name, 'result': True, 'comment': '', 'changes': {}}
    dashboard = dashboard or {}

    if isinstance(profile, six.string_types):
        profile = __salt__['config.option'](profile)

    if dashboard_format == 'json':
        # In this case, a raw JSON of the full dashboard is provided.
        response = _update(dashboard, profile)

        if response.get('status') == 'success':
            ret['comment'] = 'Dashboard {0} created.'.format(name)
            ret['changes']['new'] = 'Dashboard {0} created.'.format(name)
        else:
            ret['result'] = False
            ret['comment'] = ("Failed to create dashboard {0}, "
                              "response={1}").format(name, response)

        return ret

    base_dashboards_from_pillar = base_dashboards_from_pillar or []
    base_panels_from_pillar = base_panels_from_pillar or []
    base_rows_from_pillar = base_rows_from_pillar or []

    # Add pillar keys for default configuration
    base_dashboards_from_pillar = ([_DEFAULT_DASHBOARD_PILLAR] +
                                   base_dashboards_from_pillar)
    base_panels_from_pillar = ([_DEFAULT_PANEL_PILLAR] +
                               base_panels_from_pillar)
    base_rows_from_pillar = [_DEFAULT_ROW_PILLAR] + base_rows_from_pillar

    # Build out all dashboard fields
    new_dashboard = _inherited_dashboard(
        dashboard, base_dashboards_from_pillar, ret)
    if not new_dashboard.get('title'):
        new_dashboard['title'] = name
    rows = new_dashboard.get('rows', [])
    for i, row in enumerate(rows):
        rows[i] = _inherited_row(row, base_rows_from_pillar, ret)
    for row in rows:
        panels = row.get('panels', [])
        for i, panel in enumerate(sorted(panels)):
            panels[i] = _inherited_panel(panel, base_panels_from_pillar, ret)
    _auto_adjust_panel_spans(new_dashboard)
    _ensure_panel_ids(new_dashboard)
    _ensure_annotations(new_dashboard)

    # Create dashboard if it does not exist
    url = 'db/{0}'.format(name)
    old_dashboard = _get(url, profile)
    if not old_dashboard:
        if __opts__['test']:
            ret['result'] = None
            ret['comment'] = 'Dashboard {0} is set to be created.'.format(name)
            return ret

        response = _update(new_dashboard, profile)
        if response.get('status') == 'success':
            ret['comment'] = 'Dashboard {0} created.'.format(name)
            ret['changes']['new'] = 'Dashboard {0} created.'.format(name)
        else:
            ret['result'] = False
            ret['comment'] = ("Failed to create dashboard {0}, "
                              "response={1}").format(name, response)
        return ret

    # Add unmanaged rows to the dashboard. They appear at the top if they are
    # marked as pinned. They appear at the bottom otherwise.
    managed_row_titles = [row.get('title')
                          for row in new_dashboard.get('rows', [])]
    new_rows = new_dashboard.get('rows', [])
    for old_row in old_dashboard.get('rows', []):
        if old_row.get('title') not in managed_row_titles:
            new_rows.append(copy.deepcopy(old_row))
    _ensure_pinned_rows(new_dashboard)
    _ensure_panel_ids(new_dashboard)

    # Update dashboard if it differs
    dashboard_diff = DictDiffer(_cleaned(new_dashboard),
                                _cleaned(old_dashboard))
    updated_needed = (dashboard_diff.changed() or
                      dashboard_diff.added() or
                      dashboard_diff.removed())
    if updated_needed:
        if __opts__['test']:
            ret['result'] = None
            ret['comment'] = ('Dashboard {0} is set to be updated, '
                              'changes={1}').format(
                                  name,
                                  json.dumps(
                                      _dashboard_diff(
                                          _cleaned(new_dashboard),
                                          _cleaned(old_dashboard)
                                      ),
                                      indent=4
                                  ))
            return ret

        response = _update(new_dashboard, profile)
        if response.get('status') == 'success':
            updated_dashboard = _get(url, profile)
            dashboard_diff = DictDiffer(_cleaned(updated_dashboard),
                                        _cleaned(old_dashboard))
            ret['comment'] = 'Dashboard {0} updated.'.format(name)
            ret['changes'] = _dashboard_diff(_cleaned(new_dashboard),
                                             _cleaned(old_dashboard))
        else:
            ret['result'] = False
            ret['comment'] = ("Failed to update dashboard {0}, "
                              "response={1}").format(name, response)
        return ret

    ret['comment'] = 'Dashboard present'
    return ret


def absent(name, profile='grafana'):
    '''
    Ensure the named grafana dashboard is absent.

    name
        Name of the grafana dashboard.

    profile
        A pillar key or dict that contains grafana information
    '''
    ret = {'name': name, 'result': True, 'comment': '', 'changes': {}}

    if isinstance(profile, six.string_types):
        profile = __salt__['config.option'](profile)

    url = 'db/{0}'.format(name)
    existing_dashboard = _get(url, profile)
    if existing_dashboard:
        if __opts__['test']:
            ret['result'] = None
            ret['comment'] = 'Dashboard {0} is set to be deleted.'.format(name)
            return ret

        _delete(url, profile)
        ret['comment'] = 'Dashboard {0} deleted.'.format(name)
        ret['changes']['new'] = 'Dashboard {0} deleted.'.format(name)
        return ret

    ret['comment'] = 'Dashboard absent'
    return ret


_IGNORED_DASHBOARD_FIELDS = [
    'id',
    'originalTitle',
    'version',
]
_IGNORED_ROW_FIELDS = []
_IGNORED_PANEL_FIELDS = [
    'grid',
    'mode',
    'tooltip',
]
_IGNORED_TARGET_FIELDS = [
    'textEditor',
]


def _cleaned(_dashboard):
    '''Return a copy without fields that can differ.'''
    dashboard = copy.deepcopy(_dashboard)

    for ignored_dashboard_field in _IGNORED_DASHBOARD_FIELDS:
        dashboard.pop(ignored_dashboard_field, None)
    for row in dashboard.get('rows', []):
        for ignored_row_field in _IGNORED_ROW_FIELDS:
            row.pop(ignored_row_field, None)
        for i, panel in enumerate(row.get('panels', [])):
            for ignored_panel_field in _IGNORED_PANEL_FIELDS:
                panel.pop(ignored_panel_field, None)
            for target in panel.get('targets', []):
                for ignored_target_field in _IGNORED_TARGET_FIELDS:
                    target.pop(ignored_target_field, None)
            row['panels'][i] = _stripped(panel)

    return dashboard


def _inherited_dashboard(dashboard, base_dashboards_from_pillar, ret):
    '''Return a dashboard with properties from parents.'''
    base_dashboards = []
    for base_dashboard_from_pillar in base_dashboards_from_pillar:
        base_dashboard = __salt__['pillar.get'](base_dashboard_from_pillar)
        if base_dashboard:
            base_dashboards.append(base_dashboard)
        elif base_dashboard_from_pillar != _DEFAULT_DASHBOARD_PILLAR:
            ret.setdefault('warnings', [])
            warning_message = 'Cannot find dashboard pillar "{0}".'.format(
                base_dashboard_from_pillar)
            if warning_message not in ret['warnings']:
                ret['warnings'].append(warning_message)
    base_dashboards.append(dashboard)

    result_dashboard = {}
    tags = set()
    for dashboard in base_dashboards:
        tags.update(dashboard.get('tags', []))
        result_dashboard.update(dashboard)
    result_dashboard['tags'] = list(tags)
    return result_dashboard


def _inherited_row(row, base_rows_from_pillar, ret):
    '''Return a row with properties from parents.'''
    base_rows = []
    for base_row_from_pillar in base_rows_from_pillar:
        base_row = __salt__['pillar.get'](base_row_from_pillar)
        if base_row:
            base_rows.append(base_row)
        elif base_row_from_pillar != _DEFAULT_ROW_PILLAR:
            ret.setdefault('warnings', [])
            warning_message = 'Cannot find row pillar "{0}".'.format(
                base_row_from_pillar)
            if warning_message not in ret['warnings']:
                ret['warnings'].append(warning_message)
    base_rows.append(row)

    result_row = {}
    for row in base_rows:
        result_row.update(row)
    return result_row


def _inherited_panel(panel, base_panels_from_pillar, ret):
    '''Return a panel with properties from parents.'''
    base_panels = []
    for base_panel_from_pillar in base_panels_from_pillar:
        base_panel = __salt__['pillar.get'](base_panel_from_pillar)
        if base_panel:
            base_panels.append(base_panel)
        elif base_panel_from_pillar != _DEFAULT_PANEL_PILLAR:
            ret.setdefault('warnings', [])
            warning_message = 'Cannot find panel pillar "{0}".'.format(
                base_panel_from_pillar)
            if warning_message not in ret['warnings']:
                ret['warnings'].append(warning_message)
    base_panels.append(panel)

    result_panel = {}
    for panel in base_panels:
        result_panel.update(panel)
    return result_panel


_FULL_LEVEL_SPAN = 12
_DEFAULT_PANEL_SPAN = 2.5


def _auto_adjust_panel_spans(dashboard):
    '''Adjust panel spans to take up the available width.

    For each group of panels that would be laid out on the same level, scale up
    the unspecified panel spans to fill up the level.
    '''
    for row in dashboard.get('rows', []):
        levels = []
        current_level = []
        levels.append(current_level)
        for panel in row.get('panels', []):
            current_level_span = sum(panel.get('span', _DEFAULT_PANEL_SPAN)
                                     for panel in current_level)
            span = panel.get('span', _DEFAULT_PANEL_SPAN)
            if current_level_span + span > _FULL_LEVEL_SPAN:
                current_level = [panel]
                levels.append(current_level)
            else:
                current_level.append(panel)

        for level in levels:
            specified_panels = [panel for panel in level if 'span' in panel]
            unspecified_panels = [panel for panel in level
                                  if 'span' not in panel]
            if not unspecified_panels:
                continue

            specified_span = sum(panel['span'] for panel in specified_panels)
            available_span = _FULL_LEVEL_SPAN - specified_span
            auto_span = float(available_span) / len(unspecified_panels)
            for panel in unspecified_panels:
                panel['span'] = auto_span


def _ensure_pinned_rows(dashboard):
    '''Pin rows to the top of the dashboard.'''
    pinned_row_titles = __salt__['pillar.get'](_PINNED_ROWS_PILLAR)
    if not pinned_row_titles:
        return

    pinned_row_titles_lower = []
    for title in pinned_row_titles:
        pinned_row_titles_lower.append(title.lower())
    rows = dashboard.get('rows', [])
    pinned_rows = []
    for i, row in enumerate(rows):
        if row.get('title', '').lower() in pinned_row_titles_lower:
            del rows[i]
            pinned_rows.append(row)
    rows = pinned_rows + rows


def _ensure_panel_ids(dashboard):
    '''Assign panels auto-incrementing IDs.'''
    panel_id = 1
    for row in dashboard.get('rows', []):
        for panel in row.get('panels', []):
            panel['id'] = panel_id
            panel_id += 1


def _ensure_annotations(dashboard):
    '''Explode annotation_tags into annotations.'''
    if 'annotation_tags' not in dashboard:
        return
    tags = dashboard['annotation_tags']
    annotations = {
        'enable': True,
        'list': [],
    }
    for tag in tags:
        annotations['list'].append({
            'datasource': "graphite",
            'enable': False,
            'iconColor': "#C0C6BE",
            'iconSize': 13,
            'lineColor': "rgba(255, 96, 96, 0.592157)",
            'name': tag,
            'showLine': True,
            'tags': tag,
        })
    del dashboard['annotation_tags']
    dashboard['annotations'] = annotations


def _get(url, profile):
    '''Get a specific dashboard.'''
    request_url = "{0}/api/dashboards/{1}".format(profile.get('grafana_url'),
                                                  url)
    if profile.get('grafana_token', False):
        response = requests.get(
            request_url,
            headers=_get_headers(profile),
            timeout=profile.get('grafana_timeout', 3),
        )
    else:
        response = requests.get(
            request_url,
            auth=_get_auth(profile),
            timeout=profile.get('grafana_timeout', 3),
        )
    data = response.json()
    if data.get('message') == 'Not found':
        return None
    if 'dashboard' not in data:
        return None
    return data['dashboard']


def _delete(url, profile):
    '''Delete a specific dashboard.'''
    request_url = "{0}/api/dashboards/{1}".format(profile.get('grafana_url'),
                                                  url)
    response = requests.delete(
        request_url,
        auth=_get_auth(profile),
        headers=_get_headers(profile),
        timeout=profile.get('grafana_timeout'),
    )
    data = response.json()
    return data


def _update(dashboard, profile):
    '''Update a specific dashboard.'''
    payload = {
        'dashboard': dashboard,
        'overwrite': True
    }
    response = requests.post(
        "{0}/api/dashboards/db".format(profile.get('grafana_url')),
        auth=_get_auth(profile),
        headers=_get_headers(profile),
        json=payload
    )
    return response.json()


def _get_headers(profile):
    headers = {'Content-type': 'application/json'}

    if profile.get('grafana_token', False):
        headers['Authorization'] = 'Bearer {0}'.format(profile['grafana_token'])

    return headers


def _get_auth(profile):
    if profile.get('grafana_token', False):
        return None

    return requests.auth.HTTPBasicAuth(
        profile['grafana_user'],
        profile['grafana_password']
    )


def _dashboard_diff(_new_dashboard, _old_dashboard):
    '''Return a dictionary of changes between dashboards.'''
    diff = {}

    # Dashboard diff
    new_dashboard = copy.deepcopy(_new_dashboard)
    old_dashboard = copy.deepcopy(_old_dashboard)
    dashboard_diff = DictDiffer(new_dashboard, old_dashboard)
    diff['dashboard'] = _stripped({
        'changed': list(dashboard_diff.changed()) or None,
        'added': list(dashboard_diff.added()) or None,
        'removed': list(dashboard_diff.removed()) or None,
    })

    # Row diff
    new_rows = new_dashboard.get('rows', [])
    old_rows = old_dashboard.get('rows', [])
    new_rows_by_title = {}
    old_rows_by_title = {}
    for row in new_rows:
        if 'title' in row:
            new_rows_by_title[row['title']] = row
    for row in old_rows:
        if 'title' in row:
            old_rows_by_title[row['title']] = row
    rows_diff = DictDiffer(new_rows_by_title, old_rows_by_title)
    diff['rows'] = _stripped({
        'added': list(rows_diff.added()) or None,
        'removed': list(rows_diff.removed()) or None,
    })
    for changed_row_title in rows_diff.changed():
        old_row = old_rows_by_title[changed_row_title]
        new_row = new_rows_by_title[changed_row_title]
        row_diff = DictDiffer(new_row, old_row)
        diff['rows'].setdefault('changed', {})
        diff['rows']['changed'][changed_row_title] = _stripped({
            'changed': list(row_diff.changed()) or None,
            'added': list(row_diff.added()) or None,
            'removed': list(row_diff.removed()) or None,
        })

    # Panel diff
    old_panels_by_id = {}
    new_panels_by_id = {}
    for row in old_dashboard.get('rows', []):
        for panel in row.get('panels', []):
            if 'id' in panel:
                old_panels_by_id[panel['id']] = panel
    for row in new_dashboard.get('rows', []):
        for panel in row.get('panels', []):
            if 'id' in panel:
                new_panels_by_id[panel['id']] = panel
    panels_diff = DictDiffer(new_panels_by_id, old_panels_by_id)
    diff['panels'] = _stripped({
        'added': list(panels_diff.added()) or None,
        'removed': list(panels_diff.removed()) or None,
    })
    for changed_panel_id in panels_diff.changed():
        old_panel = old_panels_by_id[changed_panel_id]
        new_panel = new_panels_by_id[changed_panel_id]
        panels_diff = DictDiffer(new_panel, old_panel)
        diff['panels'].setdefault('changed', {})
        diff['panels']['changed'][changed_panel_id] = _stripped({
            'changed': list(panels_diff.changed()) or None,
            'added': list(panels_diff.added()) or None,
            'removed': list(panels_diff.removed()) or None,
        })

    return diff


def _stripped(d):
    '''Strip falsey entries.'''
    ret = {}
    for k, v in six.iteritems(d):
        if v:
            ret[k] = v
    return ret
