// Copyright (C) 2022 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 m from 'mithril';
import {Attributes} from 'mithril';

import {assertExists} from '../base/logging';
import {Actions} from '../common/actions';
import {
  RecordingConfigUtils,
} from '../common/recordingV2/recording_config_utils';
import {
  ChromeTargetInfo,
  RecordingTargetV2,
  TargetInfo,
} from '../common/recordingV2/recording_interfaces_v2';
import {
  RecordingPageController,
  RecordingState,
} from '../common/recordingV2/recording_page_controller';
import {
  EXTENSION_NAME,
  EXTENSION_URL,
} from '../common/recordingV2/recording_utils';
import {
  targetFactoryRegistry,
} from '../common/recordingV2/target_factory_registry';

import {globals} from './globals';
import {fullscreenModalContainer} from './modal';
import {createPage, PageAttrs} from './pages';
import {recordConfigStore} from './record_config';
import {
  Configurations,
  maybeGetActiveCss,
  PERSIST_CONFIG_FLAG,
  RECORDING_SECTIONS,
} from './record_page';
import {CodeSnippet} from './record_widgets';
import {AdvancedSettings} from './recording/advanced_settings';
import {AndroidSettings} from './recording/android_settings';
import {ChromeSettings} from './recording/chrome_settings';
import {CpuSettings} from './recording/cpu_settings';
import {GpuSettings} from './recording/gpu_settings';
import {MemorySettings} from './recording/memory_settings';
import {PowerSettings} from './recording/power_settings';
import {RecordingSectionAttrs} from './recording/recording_sections';
import {RecordingSettings} from './recording/recording_settings';
import {
  FORCE_RESET_MESSAGE,
} from './recording/recording_ui_utils';
import {addNewTarget} from './recording/reset_target_modal';

const START_RECORDING_MESSAGE = 'Start Recording';

const controller = new RecordingPageController();
const recordConfigUtils = new RecordingConfigUtils();
// Whether the target selection modal is displayed.
let shouldDisplayTargetModal: boolean = false;

// Options for displaying a target selection menu.
export interface TargetSelectionOptions {
  // css attributes passed to the mithril components which displays the target
  // selection menu.
  attributes: Attributes;
  // Whether the selection should be preceded by a text label.
  shouldDisplayLabel: boolean;
}

function isChromeTargetInfo(targetInfo: TargetInfo):
    targetInfo is ChromeTargetInfo {
  return ['CHROME', 'CHROME_OS'].includes(targetInfo.targetType);
}

function RecordHeader() {
  const platformSelection = RecordingPlatformSelection();
  const statusLabel = RecordingStatusLabel();
  const buttons = RecordingButton();
  const notes = RecordingNotes();
  if (!platformSelection && !statusLabel && !buttons && !notes) {
    // The header should not be displayed when it has no content.
    return undefined;
  }
  return m(
      '.record-header',
      m('.top-part',
        m('.target-and-status', platformSelection, statusLabel),
        buttons),
      notes);
}

function RecordingPlatformSelection() {
  // Don't show the platform selector while we are recording a trace.
  if (controller.getState() >= RecordingState.RECORDING) return undefined;

  return m(
      '.target',
      m('.chip',
        {
          onclick: () => {
            shouldDisplayTargetModal = true;
            fullscreenModalContainer.createNew(addNewTargetModal());
            globals.rafScheduler.scheduleFullRedraw();
          },
        },
        m('button', 'Add new recording target'),
        m('i.material-icons', 'add')),
      targetSelection());
}

function addNewTargetModal() {
  return {
    ...addNewTarget(controller),
    onClose: () => shouldDisplayTargetModal = false,
  };
}

export function targetSelection(): m.Vnode|undefined {
  if (!controller.shouldShowTargetSelection()) {
    return undefined;
  }

  const targets: RecordingTargetV2[] = targetFactoryRegistry.listTargets();
  const targetNames = [];
  const targetInfo = controller.getTargetInfo();
  if (!targetInfo) {
    targetNames.push(m('option', 'PLEASE_SELECT_TARGET'));
  }

  let selectedIndex = 0;
  for (let i = 0; i < targets.length; i++) {
    const targetName = targets[i].getInfo().name;
    targetNames.push(m('option', targetName));
    if (targetInfo && targetName === targetInfo.name) {
      selectedIndex = i;
    }
  }

  return m(
      'label',
      'Target platform:',
      m('select',
        {
          selectedIndex,
          onchange: (e: Event) => {
            controller.onTargetSelection((e.target as HTMLSelectElement).value);
          },
          onupdate: (select) => {
            // Work around mithril bug
            // (https://github.com/MithrilJS/mithril.js/issues/2107): We may
            // update the select's options while also changing the
            // selectedIndex at the same time. The update of selectedIndex
            // may be applied before the new options are added to the select
            // element. Because the new selectedIndex may be outside of the
            // select's options at that time, we have to reselect the
            // correct index here after any new children were added.
            (select.dom as HTMLSelectElement).selectedIndex = selectedIndex;
          },
        },
        ...targetNames),
  );
}

// This will display status messages which are informative, but do not require
// user action, such as: "Recording in progress for X seconds" in the recording
// page header.
function RecordingStatusLabel() {
  const recordingStatus = globals.state.recordingStatus;
  if (!recordingStatus) return undefined;
  return m('label', recordingStatus);
}

function Instructions(cssClass: string) {
  if (controller.getState() < RecordingState.TARGET_SELECTED) {
    return undefined;
  }
  // We will have a valid target at this step because we checked the state.
  const targetInfo = assertExists(controller.getTargetInfo());

  return m(
      `.record-section.instructions${cssClass}`,
      m('header', 'Recording command'),
      (PERSIST_CONFIG_FLAG.get()) ?
          m('button.permalinkconfig',
            {
              onclick: () => {
                globals.dispatch(
                    Actions.createPermalink({isRecordingConfig: true}));
              },
            },
            'Share recording settings') :
          null,
      RecordingSnippet(targetInfo),
      BufferUsageProgressBar(),
      m('.buttons', StopCancelButtons()));
}

function BufferUsageProgressBar() {
  // Show the Buffer Usage bar only after we start recording a trace.
  if (controller.getState() !== RecordingState.RECORDING) {
    return undefined;
  }

  controller.fetchBufferUsage();

  const bufferUsage = controller.getBufferUsagePercentage();
  // Buffer usage is not available yet on Android.
  if (bufferUsage === 0) return undefined;

  return m(
      'label',
      'Buffer usage: ',
      m('progress', {max: 100, value: bufferUsage * 100}));
}

function RecordingNotes() {
  if (controller.getState() !== RecordingState.TARGET_INFO_DISPLAYED) {
    return undefined;
  }
  // We will have a valid target at this step because we checked the state.
  const targetInfo = assertExists(controller.getTargetInfo());

  const linuxUrl = 'https://perfetto.dev/docs/quickstart/linux-tracing';
  const cmdlineUrl =
      'https://perfetto.dev/docs/quickstart/android-tracing#perfetto-cmdline';

  const notes: m.Children = [];

  const msgFeatNotSupported =
      m('span', `Some probes are only supported in Perfetto versions running
      on Android Q+. Therefore, Perfetto will sideload the latest version onto 
      the device.`);

  const msgPerfettoNotSupported = m(
      'span',
      `Perfetto is not supported natively before Android P. Therefore, Perfetto 
       will sideload the latest version onto the device.`);

  const msgLinux =
      m('.note',
        `Use this `,
        m('a', {href: linuxUrl, target: '_blank'}, `quickstart guide`),
        ` to get started with tracing on Linux.`);

  const msgLongTraces = m(
      '.note',
      `Recording in long trace mode through the UI is not supported. Please copy
    the command and `,
      m('a',
        {href: cmdlineUrl, target: '_blank'},
        `collect the trace using ADB.`));

  if (!recordConfigUtils
           .fetchLatestRecordCommand(globals.state.recordConfig, targetInfo)
           .hasDataSources) {
    notes.push(
        m('.note',
          'It looks like you didn\'t add any probes. ' +
              'Please add at least one to get a non-empty trace.'));
  }

  targetFactoryRegistry.listRecordingProblems().map((recordingProblem) => {
    if (recordingProblem.includes(EXTENSION_URL)) {
      // Special case for rendering the link to the Chrome extension.
      const parts = recordingProblem.split(EXTENSION_URL);
      notes.push(
          m('.note',
            parts[0],
            m('a', {href: EXTENSION_URL, target: '_blank'}, EXTENSION_NAME),
            parts[1]));
    }
  });

  switch (targetInfo.targetType) {
    case 'LINUX':
      notes.push(msgLinux);
      break;
    case 'ANDROID': {
      const androidApiLevel = targetInfo.androidApiLevel;
      if (androidApiLevel === 28) {
        notes.push(m('.note', msgFeatNotSupported));
      } else if (androidApiLevel && androidApiLevel <= 27) {
        notes.push(m('.note', msgPerfettoNotSupported));
      }
      break;
    }
    default:
  }

  if (globals.state.recordConfig.mode === 'LONG_TRACE') {
    notes.unshift(msgLongTraces);
  }

  return notes.length > 0 ? m('div', notes) : undefined;
}

function RecordingSnippet(targetInfo: TargetInfo) {
  // We don't need commands to start tracing on chrome
  if (isChromeTargetInfo(targetInfo)) {
    if (controller.getState() > RecordingState.AUTH_P2) {
      // If the UI has started tracing, don't display a message guiding the user
      // to start recording.
      return undefined;
    }
    return m(
        'div',
        m('label', `To trace Chrome from the Perfetto UI you just have to press
         '${START_RECORDING_MESSAGE}'.`));
  }
  return m(CodeSnippet, {text: getRecordCommand(targetInfo)});
}

function getRecordCommand(targetInfo: TargetInfo): string {
  const recordCommand = recordConfigUtils.fetchLatestRecordCommand(
      globals.state.recordConfig, targetInfo);

  const pbBase64 = recordCommand ? recordCommand.configProtoBase64 : '';
  const pbtx = recordCommand ? recordCommand.configProtoText : '';
  let cmd = '';
  if (targetInfo.targetType === 'ANDROID' &&
      targetInfo.androidApiLevel === 28) {
    cmd += `echo '${pbBase64}' | \n`;
    cmd += 'base64 --decode | \n';
    cmd += 'adb shell "perfetto -c - -o /data/misc/perfetto-traces/trace"\n';
  } else {
    cmd += targetInfo.targetType === 'ANDROID' ? 'adb shell perfetto \\\n' :
                                                 'perfetto \\\n';
    cmd += '  -c - --txt \\\n';
    cmd += '  -o /data/misc/perfetto-traces/trace \\\n';
    cmd += '<<EOF\n\n';
    cmd += pbtx;
    cmd += '\nEOF\n';
  }
  return cmd;
}

function RecordingButton() {
  if (controller.getState() !== RecordingState.TARGET_INFO_DISPLAYED ||
      !controller.canCreateTracingSession()) {
    return undefined;
  }

  // We know we have a target because we checked the state.
  const targetInfo = assertExists(controller.getTargetInfo());
  const hasDataSources =
      recordConfigUtils
          .fetchLatestRecordCommand(globals.state.recordConfig, targetInfo)
          .hasDataSources;
  if (!hasDataSources) {
    return undefined;
  }

  return m(
      '.button',
      m('button',
        {
          class: 'selected',
          onclick: () => controller.onStartRecordingPressed(),
        },
        START_RECORDING_MESSAGE));
}

function StopCancelButtons() {
  // Show the Stop/Cancel buttons only while we are recording a trace.
  if (!controller.shouldShowStopCancelButtons()) {
    return undefined;
  }

  const stop =
      m(`button.selected`, {onclick: () => controller.onStop()}, 'Stop');

  const cancel = m(`button`, {onclick: () => controller.onCancel()}, 'Cancel');

  return [stop, cancel];
}

function recordMenu(routePage: string) {
  const chromeProbe =
      m('a[href="#!/record/chrome"]',
        m(`li${routePage === 'chrome' ? '.active' : ''}`,
          m('i.material-icons', 'laptop_chromebook'),
          m('.title', 'Chrome'),
          m('.sub', 'Chrome traces')));
  const cpuProbe =
      m('a[href="#!/record/cpu"]',
        m(`li${routePage === 'cpu' ? '.active' : ''}`,
          m('i.material-icons', 'subtitles'),
          m('.title', 'CPU'),
          m('.sub', 'CPU usage, scheduling, wakeups')));
  const gpuProbe =
      m('a[href="#!/record/gpu"]',
        m(`li${routePage === 'gpu' ? '.active' : ''}`,
          m('i.material-icons', 'aspect_ratio'),
          m('.title', 'GPU'),
          m('.sub', 'GPU frequency, memory')));
  const powerProbe =
      m('a[href="#!/record/power"]',
        m(`li${routePage === 'power' ? '.active' : ''}`,
          m('i.material-icons', 'battery_charging_full'),
          m('.title', 'Power'),
          m('.sub', 'Battery and other energy counters')));
  const memoryProbe =
      m('a[href="#!/record/memory"]',
        m(`li${routePage === 'memory' ? '.active' : ''}`,
          m('i.material-icons', 'memory'),
          m('.title', 'Memory'),
          m('.sub', 'Physical mem, VM, LMK')));
  const androidProbe =
      m('a[href="#!/record/android"]',
        m(`li${routePage === 'android' ? '.active' : ''}`,
          m('i.material-icons', 'android'),
          m('.title', 'Android apps & svcs'),
          m('.sub', 'atrace and logcat')));
  const advancedProbe =
      m('a[href="#!/record/advanced"]',
        m(`li${routePage === 'advanced' ? '.active' : ''}`,
          m('i.material-icons', 'settings'),
          m('.title', 'Advanced settings'),
          m('.sub', 'Complicated stuff for wizards')));

  // We only display the probes when we have a valid target, so it's not
  // possible for the target to be undefined here.
  const targetType = assertExists(controller.getTargetInfo()).targetType;
  const probes = [];
  if (targetType === 'CHROME_OS' || targetType === 'LINUX') {
    probes.push(cpuProbe, powerProbe, memoryProbe, chromeProbe, advancedProbe);
  } else if (targetType === 'CHROME') {
    probes.push(chromeProbe);
  } else {
    probes.push(
        cpuProbe,
        gpuProbe,
        powerProbe,
        memoryProbe,
        androidProbe,
        chromeProbe,
        advancedProbe);
  }

  return m(
      '.record-menu',
      {
        class: controller.getState() > RecordingState.TARGET_INFO_DISPLAYED ?
            'disabled' :
            '',
        onclick: () => globals.rafScheduler.scheduleFullRedraw(),
      },
      m('header', 'Trace config'),
      m('ul',
        m('a[href="#!/record/buffers"]',
          m(`li${routePage === 'buffers' ? '.active' : ''}`,
            m('i.material-icons', 'tune'),
            m('.title', 'Recording settings'),
            m('.sub', 'Buffer mode, size and duration'))),
        m('a[href="#!/record/instructions"]',
          m(`li${routePage === 'instructions' ? '.active' : ''}`,
            m('i.material-icons-filled.rec', 'fiber_manual_record'),
            m('.title', 'Recording command'),
            m('.sub', 'Manually record trace'))),
        PERSIST_CONFIG_FLAG.get() ?
            m('a[href="#!/record/config"]',
              {
                onclick: () => {
                  recordConfigStore.reloadFromLocalStorage();
                },
              },
              m(`li${routePage === 'config' ? '.active' : ''}`,
                m('i.material-icons', 'save'),
                m('.title', 'Saved configs'),
                m('.sub', 'Manage local configs'))) :
            null),
      m('header', 'Probes'),
      m('ul', probes));
}

function getRecordContainer(subpage?: string): m.Vnode<any, any> {
  const components: m.Children[] = [RecordHeader()];
  if (controller.getState() === RecordingState.NO_TARGET) {
    components.push(m('.full-centered', 'Please connect a valid target.'));
    return m('.record-container', components);
  } else if (controller.getState() <= RecordingState.ASK_TO_FORCE_P1) {
    components.push(
        m('.full-centered',
          'Can not access the device without resetting the ' +
              `connection. Please refresh the page, then click ` +
              `'${FORCE_RESET_MESSAGE}.'`));
    return m('.record-container', components);
  } else if (controller.getState() === RecordingState.AUTH_P1) {
    components.push(
        m('.full-centered', 'Please allow USB debugging on the device.'));
    return m('.record-container', components);
  } else if (
      controller.getState() === RecordingState.WAITING_FOR_TRACE_DISPLAY) {
    components.push(
        m('.full-centered', 'Waiting for the trace to be collected.'));
    return m('.record-container', components);
  }

  const pages: m.Children = [];
  // we need to remove the `/` character from the route
  let routePage = subpage ? subpage.substr(1) : '';
  if (!RECORDING_SECTIONS.includes(routePage)) {
    routePage = 'buffers';
  }
  pages.push(recordMenu(routePage));

  pages.push(m(RecordingSettings, {
    dataSources: [],
    cssClass: maybeGetActiveCss(routePage, 'buffers'),
  } as RecordingSectionAttrs));
  pages.push(Instructions(maybeGetActiveCss(routePage, 'instructions')));
  pages.push(Configurations(maybeGetActiveCss(routePage, 'config')));

  const settingsSections = new Map([
    ['cpu', CpuSettings],
    ['gpu', GpuSettings],
    ['power', PowerSettings],
    ['memory', MemorySettings],
    ['android', AndroidSettings],
    ['chrome', ChromeSettings],
    ['advanced', AdvancedSettings],
  ]);
  for (const [section, component] of settingsSections.entries()) {
    pages.push(m(component, {
      dataSources: controller.getTargetInfo()?.dataSources || [],
      cssClass: maybeGetActiveCss(routePage, section),
    } as RecordingSectionAttrs));
  }

  components.push(m('.record-container-content', pages));
  return m('.record-container', components);
}

export const RecordPageV2 = createPage({

  oninit(): void {
    controller.initFactories();
  },

  view({attrs}: m.Vnode<PageAttrs>): void |
      m.Children {
        if (shouldDisplayTargetModal) {
          fullscreenModalContainer.updateVdom(addNewTargetModal());
        }

        return m(
            '.record-page',
            controller.getState() > RecordingState.TARGET_INFO_DISPLAYED ?
                m('.hider') :
                [],
            getRecordContainer(attrs.subpage));
      },
});
