// Copyright (C) 2018 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 * as m from 'mithril';

import {assertExists} from '../base/logging';
import {Actions} from '../common/actions';
import {HttpRpcEngine, RPC_URL} from '../common/http_rpc_engine';
import {StatusResult} from '../common/protos';
import * as version from '../gen/perfetto_version';
import {perfetto} from '../gen/protos';

import {globals} from './globals';
import {showModal} from './modal';

const CURRENT_API_VERSION = perfetto.protos.TraceProcessorApiVersion
                                .TRACE_PROCESSOR_CURRENT_API_VERSION;

const PROMPT = `Trace Processor Native Accelerator detected on ${RPC_URL} with:
$loadedTraceName

YES, use loaded trace:
Will load from the current state of Trace Processor. If you did run
trace_processor_shell --httpd file.pftrace this is likely what you want.

YES, but reset state:
Use this if you want to open another trace but still use the
accelerator. This is the equivalent of killing and restarting
trace_processor_shell --httpd.

NO, Use builtin WASM:
Will not use the accelerator in this tab.

Using the native accelerator has some minor caveats:
- Only one tab can be using the accelerator.
- Sharing, downloading and conversion-to-legacy aren't supported.
- You may encounter UI errors if the Trace Processor version you are using is
too old. Get the latest version from get.perfetto.dev/trace_processor.
`;


const MSG_TOO_OLD = `The Trace Processor instance on ${RPC_URL} is too old.

This UI requires TraceProcessor features that are not present in the
Trace Processor native accelerator you are currently running.
If you continue, this is almost surely going to cause UI failures.

Please update your local Trace Processor binary:

curl -LO https://get.perfetto.dev/trace_processor
chmod +x ./trace_processor
./trace_processor --httpd

UI version: ${version.VERSION}
TraceProcessor RPC API required: ${CURRENT_API_VERSION} or higher

TraceProcessor version: $tpVersion
RPC API: $tpApi
`;

let forceUseOldVersion = false;

// Try to connect to the external Trace Processor HTTP RPC accelerator (if
// available, often it isn't). If connected it will populate the
// |httpRpcState| in the frontend local state. In turn that will show the UI
// chip in the sidebar. trace_controller.ts will repeat this check before
// trying to load a new trace. We do this ahead of time just to have a
// consistent UX (i.e. so that the user can tell if the RPC is working without
// having to open a trace).
export async function CheckHttpRpcConnection(): Promise<void> {
  const state = await HttpRpcEngine.checkConnection();
  globals.frontendLocalState.setHttpRpcState(state);
  if (!state.connected) return;
  const tpStatus = assertExists(state.status);

  if (tpStatus.apiVersion < CURRENT_API_VERSION) {
    await showDialogTraceProcessorTooOld(tpStatus);
    if (!forceUseOldVersion) return;
  }

  if (tpStatus.loadedTraceName) {
    // If a trace is already loaded in the trace processor (e.g., the user
    // launched trace_processor_shell -D trace_file.pftrace), prompt the user to
    // initialize the UI with the already-loaded trace.
    return showDialogToUsePreloadedTrace(tpStatus);
  }
}

async function showDialogTraceProcessorTooOld(tpStatus: StatusResult) {
  return showModal({
    title: 'Your Trace Processor binary is outdated',
    content:
        m('.modal-pre',
          MSG_TOO_OLD.replace('$tpVersion', tpStatus.humanReadableVersion)
              .replace('$tpApi', `${tpStatus.apiVersion}`)),
    buttons: [
      {
        text: 'Use builtin Wasm',
        primary: true,
        action: () => {
          globals.dispatch(
              Actions.setNewEngineMode({mode: 'FORCE_BUILTIN_WASM'}));
        },
      },
      {
        text: 'Use old version regardless (might crash)',
        primary: false,
        action: () => {
          forceUseOldVersion = true;
        },
      },
    ],
  });
}

async function showDialogToUsePreloadedTrace(tpStatus: StatusResult) {
  return showModal({
    title: 'Use Trace Processor Native Acceleration?',
    content:
        m('.modal-pre',
          PROMPT.replace('$loadedTraceName', tpStatus.loadedTraceName)),
    buttons: [
      {
        text: 'YES, use loaded trace',
        primary: true,
        action: () => {
          globals.dispatch(Actions.openTraceFromHttpRpc({}));
        },
      },
      {
        text: 'YES, but reset state',
      },
      {
        text: 'NO, Use builtin Wasm',
        action: () => {
          globals.dispatch(
              Actions.setNewEngineMode({mode: 'FORCE_BUILTIN_WASM'}));
        },
      },
    ],
  });
}
