// 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 {Span, tpDurationToSeconds} from '../common/time';
import {TPDuration, TPTime, TPTimeSpan} from '../common/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): [TPDuration, 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}"`);
    }
  });
}

// Get the number of decimal places we would have to print a time to for a given
// min step size. For example, if we know the min step size is 0.1 and all
// values are going to be aligned to integral multiples of 0.1, there's no
// point printing these values with more than 1 decimal place.
// Note: It's assumed that stepSize only has one significant figure.
// E.g. 0.3 and 0.00002 are fine, but 0.123 will be treated as if it were 0.1.
// Some examples: (seconds -> decimal places)
//  1.0 -> 0
//  0.5 -> 1
//  0.009 -> 3
//  0.00007 -> 5
//  30000 -> 0
//  0.30000000000000004 -> 1
export function guessDecimalPlaces(stepSize: TPDuration): number {
  const stepSizeSeconds = tpDurationToSeconds(stepSize);
  const decimalPlaces = -Math.floor(Math.log10(stepSizeSeconds));
  return Math.max(0, decimalPlaces);
}

export enum TickType {
  MAJOR,
  MEDIUM,
  MINOR
}

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

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

function roundDownNearest(time: TPTime, stepSize: TPDuration): TPTime {
  return stepSize * (time / stepSize);
}

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

  constructor(
      timeSpan: Span<TPTime>, maxMajorTicks: number, offset: TPTime = 0n) {
    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 = roundDownNearest(this._timeSpan.start, this._patternSize);
    const end = this._timeSpan.end;
    let patternIndex = 0;

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

  get digits(): number {
    return guessDecimalPlaces(this._patternSize);
  }
}

// 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 {earliest, latest} = globals.frontendLocalState.visibleWindow;
  const span = new TPTimeSpan(earliest, latest);
  if (width > TRACK_SHELL_WIDTH && span.duration > 0n) {
    const maxMajorTicks = getMaxMajorTicks(width - TRACK_SHELL_WIDTH);
    const map = timeScaleForVisibleWindow(TRACK_SHELL_WIDTH, width);
    for (const {type, time} of new TickGenerator(
             span, maxMajorTicks, globals.state.traceTime.start)) {
      const px = Math.floor(map.tpTimeToPx(time));
      if (type === TickType.MAJOR) {
        ctx.beginPath();
        ctx.moveTo(px + 0.5, 0);
        ctx.lineTo(px + 0.5, height);
        ctx.stroke();
      }
    }
  }
}
