import _ from 'lodash';
import moment from 'moment';
import TableModel from 'grafana/app/core/table_model';
import * as utils from '../datasource-zabbix/utils';
import * as c from './constants';
import { DataFrame, Field, FieldType, ArrayVector } from '@grafana/data';
import { ZBXProblem, ZBXTrigger, ProblemDTO } from './types';

export function joinTriggersWithProblems(problems: ZBXProblem[], triggers: ZBXTrigger[]): ProblemDTO[] {
  const problemDTOList: ProblemDTO[] = [];
  for (let i = 0; i < problems.length; i++) {
    const p = problems[i];
    const triggerId = Number(p.objectid);
    const t = triggers[triggerId];
    const problemDTO: ProblemDTO = {
      timestamp: Number(p.clock),
      triggerid: p.objectid,
      eventid: p.eventid,
      name: p.name,
      severity: p.severity,
      acknowledged: p.acknowledged,
      acknowledges: p.acknowledges,
      tags: p.tags,
      suppressed: p.suppressed,
      suppression_data: p.suppression_data,
      description: t.description,
      comments: t.comments,
      value: t.value,
      groups: t.groups,
      hosts: t.hosts,
      items: t.items,
      alerts: t.alerts,
      url: t.url,
      expression: t.expression,
      correlation_mode: t.correlation_mode,
      correlation_tag: t.correlation_tag,
      manual_close: t.manual_close,
      state: t.state,
      error: t.error,
    };

    problemDTOList.push(problemDTO);
  }

  return problemDTOList;
}

export function setMaintenanceStatus(triggers) {
  _.each(triggers, (trigger) => {
    const maintenance_status = _.some(trigger.hosts, (host) => host.maintenance_status === '1');
    trigger.maintenance = maintenance_status;
  });
  return triggers;
}

export function setAckButtonStatus(triggers, showAckButton) {
  _.each(triggers, (trigger) => {
    trigger.showAckButton = showAckButton;
  });
  return triggers;
}

export function addTriggerDataSource(triggers, target) {
  _.each(triggers, (trigger) => {
    trigger.datasource = target.datasource;
  });
  return triggers;
}

export function addTriggerHostProxy(triggers, proxies) {
  triggers.forEach(trigger => {
    if (trigger.hosts && trigger.hosts.length) {
      const host = trigger.hosts[0];
      if (host.proxy_hostid !== '0') {
        const hostProxy = proxies[host.proxy_hostid];
        host.proxy = hostProxy ? hostProxy.host : '';
      }
    }
  });
  return triggers;
}

export function filterTriggersPre(triggerList, replacedTarget) {
  // Filter triggers by description
  const triggerFilter = replacedTarget.trigger.filter;
  if (triggerFilter) {
    triggerList = filterTriggers(triggerList, triggerFilter);
  }

  // Filter by tags
  if (replacedTarget.tags.filter) {
    let tagsFilter = replacedTarget.tags.filter;
    // replaceTemplateVars() builds regex-like string, so we should trim it.
    tagsFilter = tagsFilter.replace('/^', '').replace('$/', '');
    const tags = utils.parseTags(tagsFilter);
    triggerList = _.filter(triggerList, trigger => {
      return _.every(tags, tag => {
        return _.find(trigger.tags, t => t.tag === tag.tag && (!tag.value || t.value === tag.value));
      });
    });
  }

  // Filter by maintenance status
  if (!replacedTarget.options.hostsInMaintenance) {
    triggerList = _.filter(triggerList, (trigger) => !trigger.maintenance);
  }

  return triggerList;
}

function filterTriggers(triggers, triggerFilter) {
  if (utils.isRegex(triggerFilter)) {
    return _.filter(triggers, trigger => {
      return utils.buildRegex(triggerFilter).test(trigger.description);
    });
  } else {
    return _.filter(triggers, trigger => {
      return trigger.description === triggerFilter;
    });
  }
}

export function toDataFrame(problems: any[]): DataFrame {
  const problemsField: Field<any> = {
    name: 'Problems',
    type: FieldType.other,
    values: new ArrayVector(problems),
    config: {},
  };

  const response: DataFrame = {
    name: 'problems',
    fields: [problemsField],
    length: problems.length,
  };

  return response;
}

const problemsHandler = {
  addTriggerDataSource,
  addTriggerHostProxy,
  setMaintenanceStatus,
  setAckButtonStatus,
  filterTriggersPre,
  toDataFrame,
};

export default problemsHandler;
