// 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 {assertTrue} from '../base/logging';
import {duration, Span, Time, time, TimeSpan} from '../base/time';
import {Actions} from '../common/actions';
import {
  HighPrecisionTime,
  HighPrecisionTimeSpan,
} from '../common/high_precision_time';
import {
  Area,
  FrontendLocalState as FrontendState,
  Timestamped,
  VisibleState,
} from '../common/state';
import {raf} from '../core/raf_scheduler';

import {globals} from './globals';
import {ratelimit} from './rate_limiters';
import {PxSpan, TimeScale} from './time_scale';

interface Range {
  start?: number;
  end?: number;
}

function chooseLatest<T extends Timestamped>(current: T, next: T): T {
  if (next !== current && next.lastUpdate > current.lastUpdate) {
    // |next| is from state. Callers may mutate the return value of
    // this function so we need to clone |next| to prevent bad mutations
    // of state:
    return Object.assign({}, next);
  }
  return current;
}

// Immutable object describing a (high precision) time window, providing methods
// for common mutation operations (pan, zoom), and accessors for common
// properties such as spans and durations in several formats.
// This object relies on the trace time span in globals and ensures start and
// ends of the time window remain within the confines of the trace time, and
// also applies a hard-coded minimum zoom level.
export class TimeWindow {
  readonly hpTimeSpan = HighPrecisionTimeSpan.ZERO;
  readonly timeSpan = TimeSpan.ZERO;

  private readonly MIN_DURATION_NS = 10;

  constructor(start = HighPrecisionTime.ZERO, durationNanos = 1e9) {
    durationNanos = Math.max(this.MIN_DURATION_NS, durationNanos);

    const traceTimeSpan = globals.stateTraceTime();
    const traceDurationNanos = traceTimeSpan.duration.nanos;

    if (durationNanos > traceDurationNanos) {
      start = traceTimeSpan.start;
      durationNanos = traceDurationNanos;
    }

    if (start.lt(traceTimeSpan.start)) {
      start = traceTimeSpan.start;
    }

    const end = start.addNanos(durationNanos);
    if (end.gt(traceTimeSpan.end)) {
      start = traceTimeSpan.end.subNanos(durationNanos);
    }

    this.hpTimeSpan = new HighPrecisionTimeSpan(
      start,
      start.addNanos(durationNanos),
    );
    this.timeSpan = new TimeSpan(
      this.hpTimeSpan.start.toTime('floor'),
      this.hpTimeSpan.end.toTime('ceil'),
    );
  }

  static fromHighPrecisionTimeSpan(span: Span<HighPrecisionTime>): TimeWindow {
    return new TimeWindow(span.start, span.duration.nanos);
  }

  // Pan the window by certain number of seconds
  pan(offset: HighPrecisionTime) {
    return new TimeWindow(
      this.hpTimeSpan.start.add(offset),
      this.hpTimeSpan.duration.nanos,
    );
  }

  // Zoom in or out a bit centered on a specific offset from the root
  // Offset represents the center of the zoom as a normalized value between 0
  // and 1 where 0 is the start of the time window and 1 is the end
  zoom(ratio: number, offset: number) {
    const traceDuration = globals.stateTraceTime().duration;
    const minDuration = Math.min(this.MIN_DURATION_NS, traceDuration.nanos);
    const currentDurationNanos = this.hpTimeSpan.duration.nanos;
    const newDurationNanos = Math.max(
      currentDurationNanos * ratio,
      minDuration,
    );
    // Delta between new and old duration
    // +ve if new duration is shorter than old duration
    const durationDeltaNanos = currentDurationNanos - newDurationNanos;
    // If offset is 0, don't move the start at all
    // If offset if 1, move the start by the amount the duration has changed
    // If new duration is shorter - move start to right
    // If new duration is longer - move start to left
    const start = this.hpTimeSpan.start.addNanos(durationDeltaNanos * offset);
    const durationNanos = newDurationNanos;
    return new TimeWindow(start, durationNanos);
  }

  createTimeScale(startPx: number, endPx: number): TimeScale {
    return new TimeScale(
      this.hpTimeSpan.start,
      this.hpTimeSpan.duration.nanos,
      new PxSpan(startPx, endPx),
    );
  }

  get earliest(): time {
    return this.timeSpan.start;
  }

  get latest(): time {
    return this.timeSpan.end;
  }
}

/**
 * State that is shared between several frontend components, but not the
 * controller. This state is updated at 60fps.
 */
export class Timeline {
  private visibleWindow = new TimeWindow();
  private _timeScale = this.visibleWindow.createTimeScale(0, 0);
  private _windowSpan = PxSpan.ZERO;

  // This is used to calculate the tracks within a Y range for area selection.
  areaY: Range = {};

  private _visibleState: VisibleState = {
    lastUpdate: 0,
    start: Time.ZERO,
    end: Time.fromSeconds(10),
    resolution: 1n,
  };

  private _selectedArea?: Area;

  // TODO: there is some redundancy in the fact that both |visibleWindowTime|
  // and a |timeScale| have a notion of time range. That should live in one
  // place only.

  zoomVisibleWindow(ratio: number, centerPoint: number) {
    this.visibleWindow = this.visibleWindow.zoom(ratio, centerPoint);
    this._timeScale = this.visibleWindow.createTimeScale(
      this._windowSpan.start,
      this._windowSpan.end,
    );
    this.kickUpdateLocalState();
  }

  panVisibleWindow(delta: HighPrecisionTime) {
    this.visibleWindow = this.visibleWindow.pan(delta);
    this._timeScale = this.visibleWindow.createTimeScale(
      this._windowSpan.start,
      this._windowSpan.end,
    );
    this.kickUpdateLocalState();
  }

  mergeState(state: FrontendState): void {
    // This is unfortunately subtle. This class mutates this._visibleState.
    // Since we may not mutate |state| (in order to make immer's immutable
    // updates work) this means that we have to make a copy of the visibleState.
    // when updating it. We don't want to have to do that unnecessarily so
    // chooseLatest returns a shallow clone of state.visibleState *only* when
    // that is the newer state. All of these complications should vanish when
    // we remove this class.
    const previousVisibleState = this._visibleState;
    this._visibleState = chooseLatest(this._visibleState, state.visibleState);
    const visibleStateWasUpdated = previousVisibleState !== this._visibleState;
    if (visibleStateWasUpdated) {
      this.updateLocalTime(
        new HighPrecisionTimeSpan(
          HighPrecisionTime.fromTime(this._visibleState.start),
          HighPrecisionTime.fromTime(this._visibleState.end),
        ),
      );
    }
  }

  // Set the highlight box to draw
  selectArea(
    start: time,
    end: time,
    tracks = this._selectedArea ? this._selectedArea.tracks : [],
  ) {
    assertTrue(
      end >= start,
      `Impossible select area: start [${start}] >= end [${end}]`,
    );
    this._selectedArea = {start, end, tracks};
    raf.scheduleFullRedraw();
  }

  deselectArea() {
    this._selectedArea = undefined;
    raf.scheduleRedraw();
  }

  get selectedArea(): Area | undefined {
    return this._selectedArea;
  }

  private ratelimitedUpdateVisible = ratelimit(() => {
    globals.dispatch(Actions.setVisibleTraceTime(this._visibleState));
  }, 50);

  private updateLocalTime(ts: Span<HighPrecisionTime>) {
    const traceBounds = globals.stateTraceTime();
    const start = ts.start.clamp(traceBounds.start, traceBounds.end);
    const end = ts.end.clamp(traceBounds.start, traceBounds.end);
    this.visibleWindow = TimeWindow.fromHighPrecisionTimeSpan(
      new HighPrecisionTimeSpan(start, end),
    );
    this._timeScale = this.visibleWindow.createTimeScale(
      this._windowSpan.start,
      this._windowSpan.end,
    );
    this.updateResolution();
  }

  private updateResolution() {
    this._visibleState.lastUpdate = Date.now() / 1000;
    this._visibleState.resolution = globals.getCurResolution();
    this.ratelimitedUpdateVisible();
  }

  private kickUpdateLocalState() {
    this._visibleState.lastUpdate = Date.now() / 1000;
    this._visibleState.start = this.visibleWindowTime.start.toTime();
    this._visibleState.end = this.visibleWindowTime.end.toTime();
    this._visibleState.resolution = globals.getCurResolution();
    this.ratelimitedUpdateVisible();
  }

  updateVisibleTime(ts: Span<HighPrecisionTime>) {
    this.updateLocalTime(ts);
    this.kickUpdateLocalState();
  }

  // Whenever start/end px of the timeScale is changed, update
  // the resolution.
  updateLocalLimits(pxStart: number, pxEnd: number) {
    // Numbers received here can be negative or equal, but we should fix that
    // before updating the timescale.
    pxStart = Math.max(0, pxStart);
    pxEnd = Math.max(0, pxEnd);
    if (pxStart === pxEnd) pxEnd = pxStart + 1;
    this._timeScale = this.visibleWindow.createTimeScale(pxStart, pxEnd);
    this._windowSpan = new PxSpan(pxStart, pxEnd);
    this.updateResolution();
  }

  // Get the time scale for the visible window
  get visibleTimeScale(): TimeScale {
    return this._timeScale;
  }

  // Produces a TimeScale object for this time window provided start and end px
  getTimeScale(startPx: number, endPx: number): TimeScale {
    return this.visibleWindow.createTimeScale(startPx, endPx);
  }

  // Get the bounds of the window in pixels
  get windowSpan(): PxSpan {
    return this._windowSpan;
  }

  // Get the bounds of the visible window as a high-precision time span
  get visibleWindowTime(): Span<HighPrecisionTime> {
    return this.visibleWindow.hpTimeSpan;
  }

  // Get the bounds of the visible window as a time span
  get visibleTimeSpan(): Span<time, duration> {
    return this.visibleWindow.timeSpan;
  }
}
