// 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} from '../base/time';

import {TRACK_BORDER_COLOR, TRACK_SHELL_WIDTH} from './css_constants';
import {globals} from './globals';
import {TimeScale} from './time_scale';

const micros = 1000n;
const millis = 1000n * micros;
const seconds = 1000n * millis;
const minutes = 60n * seconds;
const hours = 60n * minutes;
const days = 24n * hours;

// These patterns cover the entire range of 0 - 2^63-1 nanoseconds
const patterns: [bigint, string][] = [
  [1n, '|'],
  [2n, '|:'],
  [5n, '|....'],
  [10n, '|....:....'],
  [20n, '|.:.'],
  [50n, '|....'],
  [100n, '|....:....'],
  [200n, '|.:.'],
  [500n, '|....'],
  [1n * micros, '|....:....'],
  [2n * micros, '|.:.'],
  [5n * micros, '|....'],
  [10n * micros, '|....:....'],
  [20n * micros, '|.:.'],
  [50n * micros, '|....'],
  [100n * micros, '|....:....'],
  [200n * micros, '|.:.'],
  [500n * micros, '|....'],
  [1n * millis, '|....:....'],
  [2n * millis, '|.:.'],
  [5n * millis, '|....'],
  [10n * millis, '|....:....'],
  [20n * millis, '|.:.'],
  [50n * millis, '|....'],
  [100n * millis, '|....:....'],
  [200n * millis, '|.:.'],
  [500n * millis, '|....'],
  [1n * seconds, '|....:....'],
  [2n * seconds, '|.:.'],
  [5n * seconds, '|....'],
  [10n * seconds, '|....:....'],
  [30n * seconds, '|.:.:.'],
  [1n * minutes, '|.....'],
  [2n * minutes, '|.:.'],
  [5n * minutes, '|.....'],
  [10n * minutes, '|....:....'],
  [30n * minutes, '|.:.:.'],
  [1n * hours, '|.....'],
  [2n * hours, '|.:.'],
  [6n * hours, '|.....'],
  [12n * hours, '|.....:.....'],
  [1n * days, '|.:.'],
  [2n * days, '|.:.'],
  [5n * days, '|....'],
  [10n * days, '|....:....'],
  [20n * days, '|.:.'],
  [50n * days, '|....'],
  [100n * days, '|....:....'],
  [200n * days, '|.:.'],
  [500n * days, '|....'],
  [1000n * days, '|....:....'],
  [2000n * days, '|.:.'],
  [5000n * days, '|....'],
  [10000n * days, '|....:....'],
  [20000n * days, '|.:.'],
  [50000n * days, '|....'],
  [100000n * days, '|....:....'],
  [200000n * days, '|.:.'],
];

// Returns the optimal step size and pattern of ticks within the step.
export function getPattern(minPatternSize: bigint): [duration, string] {
  for (const [size, pattern] of patterns) {
    if (size >= minPatternSize) {
      return [size, pattern];
    }
  }

  throw new Error('Pattern not defined for this minsize');
}

function tickPatternToArray(pattern: string): TickType[] {
  const array = Array.from(pattern);
  return array.map((char) => {
    switch (char) {
      case '|':
        return TickType.MAJOR;
      case ':':
        return TickType.MEDIUM;
      case '.':
        return TickType.MINOR;
      default:
        // This is almost certainly a developer/fat-finger error
        throw Error(`Invalid char "${char}" in pattern "${pattern}"`);
    }
  });
}

export enum TickType {
  MAJOR,
  MEDIUM,
  MINOR
}

export interface Tick {
  type: TickType;
  time: time;
}

export const MIN_PX_PER_STEP = 120;
export function getMaxMajorTicks(width: number) {
  return Math.max(1, Math.floor(width / MIN_PX_PER_STEP));
}

// An iterable which generates a series of ticks for a given timescale.
export class TickGenerator implements Iterable<Tick> {
  private _tickPattern: TickType[];
  private _patternSize: duration;
  private _timeSpan: Span<time, duration>;
  private _offset: time;

  constructor(
      timeSpan: Span<time, duration>, maxMajorTicks: number,
      offset: time = Time.ZERO) {
    assertTrue(timeSpan.duration > 0n, 'timeSpan.duration cannot be lte 0');
    assertTrue(maxMajorTicks > 0, 'maxMajorTicks cannot be lte 0');

    this._timeSpan = timeSpan.add(-offset);
    this._offset = offset;
    const minStepSize =
        BigInt(Math.floor(Number(timeSpan.duration) / maxMajorTicks));
    const [size, pattern] = getPattern(minStepSize);
    this._patternSize = size;
    this._tickPattern = tickPatternToArray(pattern);
  }

  // Returns an iterable, so this object can be iterated over directly using the
  // `for x of y` notation. The use of a generator here is just to make things
  // more elegant compared to creating an array of ticks and building an
  // iterator for it.
  * [Symbol.iterator](): Generator<Tick> {
    const stepSize = this._patternSize / BigInt(this._tickPattern.length);
    const start = Time.quantFloor(this._timeSpan.start, this._patternSize);
    const end = this._timeSpan.end;
    let patternIndex = 0;

    for (let time = start; time < end;
         time = Time.add(time, stepSize), patternIndex++) {
      if (time >= this._timeSpan.start) {
        patternIndex = patternIndex % this._tickPattern.length;
        const type = this._tickPattern[patternIndex];
        yield {type, time: Time.add(time, this._offset)};
      }
    }
  }
}

// Gets the timescale associated with the current visible window.
export function timeScaleForVisibleWindow(
    startPx: number, endPx: number): TimeScale {
  return globals.frontendLocalState.getTimeScale(startPx, endPx);
}

export function drawGridLines(
    ctx: CanvasRenderingContext2D,
    width: number,
    height: number): void {
  ctx.strokeStyle = TRACK_BORDER_COLOR;
  ctx.lineWidth = 1;

  const span = globals.frontendLocalState.visibleTimeSpan;
  if (width > TRACK_SHELL_WIDTH && span.duration > 0n) {
    const maxMajorTicks = getMaxMajorTicks(width - TRACK_SHELL_WIDTH);
    const map = timeScaleForVisibleWindow(TRACK_SHELL_WIDTH, width);
    const offset = globals.timestampOffset();
    for (const {type, time} of new TickGenerator(span, maxMajorTicks, offset)) {
      const px = Math.floor(map.timeToPx(time));
      if (type === TickType.MAJOR) {
        ctx.beginPath();
        ctx.moveTo(px + 0.5, 0);
        ctx.lineTo(px + 0.5, height);
        ctx.stroke();
      }
    }
  }
}
