// Copyright (C) 2021 The Android Open Source Project
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//      http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

import {Actions} from '../common/actions';
import {AggregateData, isEmptyData} from '../common/aggregation_data';
import {ConversionJobStatusUpdate} from '../common/conversion_jobs';
import {
  LogBoundsKey,
  LogEntriesKey,
  LogExists,
  LogExistsKey,
} from '../common/logs';
import {MetricResult} from '../common/metric_data';
import {CurrentSearchResults, SearchSummary} from '../common/search_data';

import {
  CounterDetails,
  CpuProfileDetails,
  FlamegraphDetails,
  Flow,
  FtracePanelData,
  FtraceStat,
  globals,
  QuantizedLoad,
  SliceDetails,
  ThreadDesc,
  ThreadStateDetails,
} from './globals';
import {findCurrentSelection} from './keyboard_event_handler';

export function publishOverviewData(
    data: {[key: string]: QuantizedLoad|QuantizedLoad[]}) {
  for (const [key, value] of Object.entries(data)) {
    if (!globals.overviewStore.has(key)) {
      globals.overviewStore.set(key, []);
    }
    if (value instanceof Array) {
      globals.overviewStore.get(key)!.push(...value);
    } else {
      globals.overviewStore.get(key)!.push(value);
    }
  }
  globals.rafScheduler.scheduleRedraw();
}

export function publishTrackData(args: {id: string, data: {}}) {
  globals.setTrackData(args.id, args.data);
  if ([LogExistsKey, LogBoundsKey, LogEntriesKey].includes(args.id)) {
    const data = globals.trackDataStore.get(LogExistsKey) as LogExists;
    if (data && data.exists) globals.rafScheduler.scheduleFullRedraw();
  } else {
    globals.rafScheduler.scheduleRedraw();
  }
}

export function publishMetricResult(metricResult: MetricResult) {
  globals.setMetricResult(metricResult);
  globals.publishRedraw();
}

export function publishSelectedFlows(selectedFlows: Flow[]) {
  globals.selectedFlows = selectedFlows;
  globals.publishRedraw();
}

export function publishCounterDetails(click: CounterDetails) {
  globals.counterDetails = click;
  globals.publishRedraw();
}

export function publishFlamegraphDetails(click: FlamegraphDetails) {
  globals.flamegraphDetails = click;
  globals.publishRedraw();
}

export function publishCpuProfileDetails(details: CpuProfileDetails) {
  globals.cpuProfileDetails = details;
  globals.publishRedraw();
}

export function publishFtraceCounters(counters: FtraceStat[]) {
  globals.ftraceCounters = counters;
  globals.publishRedraw();
}

export function publishConversionJobStatusUpdate(
    job: ConversionJobStatusUpdate) {
  globals.setConversionJobStatus(job.jobName, job.jobStatus);
  globals.publishRedraw();
}

export function publishLoading(numQueuedQueries: number) {
  globals.numQueuedQueries = numQueuedQueries;
  // TODO(hjd): Clean up loadingAnimation given that this now causes a full
  // redraw anyways. Also this should probably just go via the global state.
  globals.rafScheduler.scheduleFullRedraw();
}

export function publishBufferUsage(args: {percentage: number}) {
  globals.setBufferUsage(args.percentage);
  globals.publishRedraw();
}

export function publishSearch(args: SearchSummary) {
  globals.searchSummary = args;
  globals.publishRedraw();
}

export function publishSearchResult(args: CurrentSearchResults) {
  globals.currentSearchResults = args;
  globals.publishRedraw();
}

export function publishRecordingLog(args: {logs: string}) {
  globals.setRecordingLog(args.logs);
  globals.publishRedraw();
}

export function publishTraceErrors(numErrors: number) {
  globals.setTraceErrors(numErrors);
  globals.publishRedraw();
}

export function publishMetricError(error: string) {
  globals.setMetricError(error);
  globals.logging.logError(error, false);
  globals.publishRedraw();
}

export function publishAggregateData(
    args: {data: AggregateData, kind: string}) {
  globals.setAggregateData(args.kind, args.data);
  if (!isEmptyData(args.data)) {
    globals.dispatch(Actions.setCurrentTab({tab: args.data.tabName}));
  }
  globals.publishRedraw();
}

export function publishQueryResult(args: {id: string, data?: {}}) {
  globals.queryResults.set(args.id, args.data);
  globals.dispatch(Actions.setCurrentTab({tab: `query_result_${args.id}`}));
  globals.publishRedraw();
}

export function publishThreads(data: ThreadDesc[]) {
  globals.threads.clear();
  data.forEach((thread) => {
    globals.threads.set(thread.utid, thread);
  });
  globals.publishRedraw();
}

export function publishSliceDetails(click: SliceDetails) {
  globals.sliceDetails = click;
  const id = click.id;
  if (id !== undefined && id === globals.state.pendingScrollId) {
    findCurrentSelection();
    globals.dispatch(Actions.setCurrentTab({tab: 'slice'}));
    globals.dispatch(Actions.clearPendingScrollId({id: undefined}));
  }
  globals.publishRedraw();
}

export function publishThreadStateDetails(click: ThreadStateDetails) {
  globals.threadStateDetails = click;
  globals.publishRedraw();
}

export function publishConnectedFlows(connectedFlows: Flow[]) {
  globals.connectedFlows = connectedFlows;
  // If a chrome slice is selected and we have any flows in connectedFlows
  // we will find the flows on the right and left of that slice to set a default
  // focus. In all other cases the focusedFlowId(Left|Right) will be set to -1.
  globals.dispatch(Actions.setHighlightedFlowLeftId({flowId: -1}));
  globals.dispatch(Actions.setHighlightedFlowRightId({flowId: -1}));
  if (globals.state.currentSelection?.kind === 'CHROME_SLICE') {
    const sliceId = globals.state.currentSelection.id;
    for (const flow of globals.connectedFlows) {
      if (flow.begin.sliceId === sliceId) {
        globals.dispatch(Actions.setHighlightedFlowRightId({flowId: flow.id}));
      }
      if (flow.end.sliceId === sliceId) {
        globals.dispatch(Actions.setHighlightedFlowLeftId({flowId: flow.id}));
      }
    }
  }

  globals.publishRedraw();
}

export function publishFtracePanelData(data: FtracePanelData) {
  globals.ftracePanelData = data;
  globals.publishRedraw();
}
