// 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 {produce} from 'immer';

import {assertExists} from '../base/logging';
import {runValidator} from '../base/validators';
import {Actions} from '../common/actions';
import {ConversionJobStatus} from '../common/conversion_jobs';
import {
  createEmptyNonSerializableState,
  createEmptyState,
} from '../common/empty_state';
import {EngineConfig, ObjectById, State, STATE_VERSION} from '../common/state';
import {
  BUCKET_NAME,
  buggyToSha256,
  deserializeStateObject,
  saveState,
  toSha256,
  TraceGcsUploader,
} from '../common/upload_utils';
import {globals} from '../frontend/globals';
import {publishConversionJobStatusUpdate} from '../frontend/publish';
import {Router} from '../frontend/router';

import {Controller} from './controller';
import {RecordConfig, recordConfigValidator} from './record_config_types';
import {showModal} from '../widgets/modal';

interface MultiEngineState {
  currentEngineId?: string;
  engines: ObjectById<EngineConfig>
}

function isMultiEngineState(state: State|
                            MultiEngineState): state is MultiEngineState {
  if ((state as MultiEngineState).engines !== undefined) {
    return true;
  }
  return false;
}

export class PermalinkController extends Controller<'main'> {
  private lastRequestId?: string;
  constructor() {
    super('main');
  }

  run() {
    if (globals.state.permalink.requestId === undefined ||
        globals.state.permalink.requestId === this.lastRequestId) {
      return;
    }
    const requestId = assertExists(globals.state.permalink.requestId);
    this.lastRequestId = requestId;

    // if the |hash| is not set, this is a request to create a permalink.
    if (globals.state.permalink.hash === undefined) {
      const isRecordingConfig =
          assertExists(globals.state.permalink.isRecordingConfig);

      const jobName = 'create_permalink';
      publishConversionJobStatusUpdate({
        jobName,
        jobStatus: ConversionJobStatus.InProgress,
      });

      PermalinkController.createPermalink(isRecordingConfig)
        .then((hash) => {
          globals.dispatch(Actions.setPermalink({requestId, hash}));
        })
        .finally(() => {
          publishConversionJobStatusUpdate({
            jobName,
            jobStatus: ConversionJobStatus.NotRunning,
          });
        });
      return;
    }

    // Otherwise, this is a request to load the permalink.
    PermalinkController.loadState(globals.state.permalink.hash)
      .then((stateOrConfig) => {
        if (PermalinkController.isRecordConfig(stateOrConfig)) {
          // This permalink state only contains a RecordConfig. Show the
          // recording page with the config, but keep other state as-is.
          const validConfig =
                runValidator(recordConfigValidator, stateOrConfig as unknown)
                  .result;
          globals.dispatch(Actions.setRecordConfig({config: validConfig}));
          Router.navigate('#!/record');
          return;
        }
        globals.dispatch(Actions.setState({newState: stateOrConfig}));
        this.lastRequestId = stateOrConfig.permalink.requestId;
      });
  }

  private static upgradeState(state: State): State {
    if (state.engine !== undefined && state.engine.source.type !== 'URL') {
      // All permalink traces should be modified to have a source.type=URL
      // pointing to the uploaded trace. Due to a bug in some older version
      // of the UI (b/327049372), an upload failure can end up with a state that
      // has type=FILE but a null file object. If this happens, invalidate the
      // trace and show a message.
      showModal({
        title: 'Cannot load trace permalink',
        content: m('div', 'The permalink stored on the server is corrupted ' +
                   'and cannot be loaded.'),
      });
      return createEmptyState();
    }

    if (state.version !== STATE_VERSION) {
      const newState = createEmptyState();
      // Old permalinks from state versions prior to version 24
      // have multiple engines of which only one is identified as the
      // current engine via currentEngineId. Handle this case:
      if (isMultiEngineState(state)) {
        const engineId = state.currentEngineId;
        if (engineId !== undefined) {
          newState.engine = state.engines[engineId];
        }
      } else {
        newState.engine = state.engine;
      }

      if (newState.engine !== undefined) {
        newState.engine.ready = false;
      }
      const message = `Unable to parse old state version. Discarding state ` +
          `and loading trace.`;
      console.warn(message);
      PermalinkController.updateStatus(message);
      return newState;
    } else {
      // Loaded state is presumed to be compatible with the State type
      // definition in the app. However, a non-serializable part has to be
      // recreated.
      state.nonSerializableState = createEmptyNonSerializableState();
    }
    return state;
  }

  private static isRecordConfig(stateOrConfig: State|
                                RecordConfig): stateOrConfig is RecordConfig {
    const mode = (stateOrConfig as {mode?: string}).mode;
    return mode !== undefined &&
        ['STOP_WHEN_FULL', 'RING_BUFFER', 'LONG_TRACE'].includes(mode);
  }

  private static async createPermalink(isRecordingConfig: boolean):
      Promise<string> {
    let uploadState: State|RecordConfig = globals.state;

    if (isRecordingConfig) {
      uploadState = globals.state.recordConfig;
    } else {
      const engine = assertExists(globals.getCurrentEngine());
      let dataToUpload: File|ArrayBuffer|undefined = undefined;
      let traceName = `trace ${engine.id}`;
      if (engine.source.type === 'FILE') {
        dataToUpload = engine.source.file;
        traceName = dataToUpload.name;
      } else if (engine.source.type === 'ARRAY_BUFFER') {
        dataToUpload = engine.source.buffer;
      } else if (engine.source.type !== 'URL') {
        throw new Error(`Cannot share trace ${JSON.stringify(engine.source)}`);
      }

      if (dataToUpload !== undefined) {
        PermalinkController.updateStatus(`Uploading ${traceName}`);
        const uploader = new TraceGcsUploader(dataToUpload, () => {
          switch (uploader.state) {
          case 'UPLOADING':
            const statusTxt = `Uploading ${uploader.getEtaString()}`;
            PermalinkController.updateStatus(statusTxt);
            break;
          case 'UPLOADED':
            // Convert state to use URLs and remove permalink.
            const url = uploader.uploadedUrl;
            uploadState = produce(globals.state, (draft) => {
              assertExists(draft.engine).source = {type: 'URL', url};
              draft.permalink = {};
            });
            break;
          case 'ERROR':
            PermalinkController.updateStatus(
              `Upload failed ${uploader.error}`);
            break;
          }  // switch (state)
        });  // onProgress
        await uploader.waitForCompletion();
      }
    }

    // Upload state.
    PermalinkController.updateStatus(`Creating permalink...`);
    const hash = await saveState(uploadState);
    PermalinkController.updateStatus(`Permalink ready`);
    return hash;
  }

  private static async loadState(id: string): Promise<State|RecordConfig> {
    const url = `https://storage.googleapis.com/${BUCKET_NAME}/${id}`;
    const response = await fetch(url);
    if (!response.ok) {
      throw new Error(
        `Could not fetch permalink.\n` +
          `Are you sure the id (${id}) is correct?\n` +
          `URL: ${url}`);
    }
    const text = await response.text();
    const stateHash = await toSha256(text);
    const state = deserializeStateObject<State>(text);
    if (stateHash !== id) {
      // Old permalinks incorrectly dropped some digits from the
      // hexdigest of the SHA256. We don't want to invalidate those
      // links so we also compute the old string and try that here
      // also.
      const buggyStateHash = await buggyToSha256(text);
      if (buggyStateHash !== id) {
        throw new Error(`State hash does not match ${id} vs. ${stateHash}`);
      }
    }
    if (!this.isRecordConfig(state)) {
      return this.upgradeState(state);
    }
    return state;
  }

  private static updateStatus(msg: string): void {
    // TODO(hjd): Unify loading updates.
    globals.dispatch(Actions.updateStatus({
      msg,
      timestamp: Date.now() / 1000,
    }));
  }
}
