// 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 {Draft, produce} from 'immer';
import * as uuidv4 from 'uuid/v4';

import {assertExists} from '../base/logging';
import {Actions} from '../common/actions';
import {EngineConfig, State} from '../common/state';

import {Controller} from './controller';
import {globals} from './globals';

export const BUCKET_NAME = 'perfetto-ui-data';

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 |link| is not set, this is a request to create a permalink.
    if (globals.state.permalink.hash === undefined) {
      PermalinkController.createPermalink().then(hash => {
        globals.dispatch(Actions.setPermalink({requestId, hash}));
      });
      return;
    }

    // Otherwise, this is a request to load the permalink.
    PermalinkController.loadState(globals.state.permalink.hash).then(state => {
      globals.dispatch(Actions.setState({newState: state}));
      this.lastRequestId = state.permalink.requestId;
    });
  }

  private static async createPermalink() {
    const state = globals.state;

    // Upload each loaded trace.
    const fileToUrl = new Map<File, string>();
    for (const engine of Object.values<EngineConfig>(state.engines)) {
      if (!(engine.source instanceof File)) continue;
      PermalinkController.updateStatus(`Uploading ${engine.source.name}`);
      const url = await this.saveTrace(engine.source);
      fileToUrl.set(engine.source, url);
    }

    // Convert state to use URLs and remove permalink.
    const uploadState = produce(state, draft => {
      for (const engine of Object.values<Draft<EngineConfig>>(
               draft.engines)) {
        if (!(engine.source instanceof File)) continue;
        engine.source = fileToUrl.get(engine.source)!;
      }
      draft.permalink = {};
    });

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

  private static async saveState(state: State): Promise<string> {
    const text = JSON.stringify(state);
    const hash = await this.toSha256(text);
    const url = 'https://www.googleapis.com/upload/storage/v1/b/' +
        `${BUCKET_NAME}/o?uploadType=media` +
        `&name=${hash}&predefinedAcl=publicRead`;
    const response = await fetch(url, {
      method: 'post',
      headers: {
        'Content-Type': 'application/json; charset=utf-8',
      },
      body: text,
    });
    await response.json();

    return hash;
  }

  private static async saveTrace(trace: File): Promise<string> {
    // TODO(hjd): This should probably also be a hash but that requires
    // trace processor support.
    const name = uuidv4();
    const url = 'https://www.googleapis.com/upload/storage/v1/b/' +
        `${BUCKET_NAME}/o?uploadType=media` +
        `&name=${name}&predefinedAcl=publicRead`;
    const response = await fetch(url, {
      method: 'post',
      headers: {'Content-Type': 'application/octet-stream;'},
      body: trace,
    });
    await response.json();
    return `https://storage.googleapis.com/${BUCKET_NAME}/${name}`;
  }

  private static async loadState(id: string): Promise<State> {
    const url = `https://storage.googleapis.com/${BUCKET_NAME}/${id}`;
    const response = await fetch(url);
    const text = await response.text();
    const stateHash = await this.toSha256(text);
    const state = JSON.parse(text);
    if (stateHash !== id) {
      throw new Error(`State hash does not match ${id} vs. ${stateHash}`);
    }
    return state;
  }

  private static async toSha256(str: string): Promise<string> {
    // TODO(hjd): TypeScript bug with definition of TextEncoder.
    // tslint:disable-next-line no-any
    const buffer = new (TextEncoder as any)('utf-8').encode(str);
    const digest = await crypto.subtle.digest('SHA-256', buffer);
    return Array.from(new Uint8Array(digest)).map(x => x.toString(16)).join('');
  }

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