1import { AnnotationEvent, DataFrame, MetricFindValue } from '@grafana/data';
2import { BackendDataSourceResponse, FetchResponse, toDataQueryResponse } from '@grafana/runtime';
3
4export default class ResponseParser {
5  transformMetricFindResponse(raw: FetchResponse<BackendDataSourceResponse>): MetricFindValue[] {
6    const frames = toDataQueryResponse(raw).data as DataFrame[];
7
8    if (!frames || !frames.length) {
9      return [];
10    }
11
12    const frame = frames[0];
13
14    const values: MetricFindValue[] = [];
15    const textField = frame.fields.find((f) => f.name === '__text');
16    const valueField = frame.fields.find((f) => f.name === '__value');
17
18    if (textField && valueField) {
19      for (let i = 0; i < textField.values.length; i++) {
20        values.push({ text: '' + textField.values.get(i), value: '' + valueField.values.get(i) });
21      }
22    } else {
23      values.push(
24        ...frame.fields
25          .flatMap((f) => f.values.toArray())
26          .map((v) => ({
27            text: v,
28          }))
29      );
30    }
31
32    return Array.from(new Set(values.map((v) => v.text))).map((text) => ({
33      text,
34      value: values.find((v) => v.text === text)?.value,
35    }));
36  }
37
38  async transformAnnotationResponse(options: any, data: BackendDataSourceResponse): Promise<AnnotationEvent[]> {
39    const frames = toDataQueryResponse({ data: data }).data as DataFrame[];
40    if (!frames || !frames.length) {
41      return [];
42    }
43    const frame = frames[0];
44    const timeField = frame.fields.find((f) => f.name === 'time' || f.name === 'time_sec');
45
46    if (!timeField) {
47      throw new Error('Missing mandatory time column (with time column alias) in annotation query');
48    }
49
50    if (frame.fields.find((f) => f.name === 'title')) {
51      throw new Error('The title column for annotations is deprecated, now only a column named text is returned');
52    }
53
54    const timeEndField = frame.fields.find((f) => f.name === 'timeend');
55    const textField = frame.fields.find((f) => f.name === 'text');
56    const tagsField = frame.fields.find((f) => f.name === 'tags');
57
58    const list: AnnotationEvent[] = [];
59    for (let i = 0; i < frame.length; i++) {
60      const timeEnd = timeEndField && timeEndField.values.get(i) ? Math.floor(timeEndField.values.get(i)) : undefined;
61      list.push({
62        annotation: options.annotation,
63        time: Math.floor(timeField.values.get(i)),
64        timeEnd,
65        text: textField && textField.values.get(i) ? textField.values.get(i) : '',
66        tags:
67          tagsField && tagsField.values.get(i)
68            ? tagsField.values
69                .get(i)
70                .trim()
71                .split(/\s*,\s*/)
72            : [],
73      });
74    }
75
76    return list;
77  }
78}
79