// 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 {BigintMath} from './bigint_math';
import {Brand} from './brand';
import {assertTrue} from './logging';

// The |time| type represents trace time in the same units and domain as trace
// processor (i.e. typically boot time in nanoseconds, but most of the UI should
// be completely agnostic to this).
export type time = Brand<bigint, 'time'>;

// The |duration| type is used to represent the duration of time between two
// |time|s. The domain is irrelevant because a duration is relative.
export type duration = bigint;

// The conversion factor for converting between different time units.
const TIME_UNITS_PER_SEC = 1e9;
const TIME_UNITS_PER_MILLISEC = 1e6;

export class Time {
  // Negative time is never found in a trace - so -1 is commonly used as a flag
  // to represent a value is undefined or unset, without having to use a
  // nullable or union type.
  static readonly INVALID = Time.fromRaw(-1n);

  // The min and max possible values, considering times cannot be negative.
  static readonly MIN = Time.fromRaw(0n);
  static readonly MAX = Time.fromRaw(BigintMath.INT64_MAX);

  static readonly ZERO = Time.fromRaw(0n);

  // Cast a bigint to a |time|. Supports potentially |undefined| values.
  // I.e. it performs the following conversions:
  // - `bigint` -> `time`
  // - `bigint|undefined` -> `time|undefined`
  //
  // Use this function with caution. The function is effectively a no-op in JS,
  // but using it tells TypeScript that "this value is a time value". It's up to
  // the caller to ensure the value is in the correct units and time domain.
  //
  // If you're reaching for this function after doing some maths on a |time|
  // value and it's decayed to a |bigint| consider using the static math methods
  // in |Time| instead, as they will do the appropriate casting for you.
  static fromRaw(v: bigint): time;
  static fromRaw(v?: bigint): time|undefined;
  static fromRaw(v?: bigint): time|undefined {
    return v as (time | undefined);
  }

  // Convert seconds (number) to a time value.
  // Note: number -> BigInt conversion is relatively slow.
  static fromSeconds(seconds: number): time {
    return Time.fromRaw(BigInt(Math.floor(seconds * TIME_UNITS_PER_SEC)));
  }

  // Convert time value to seconds and return as a number (i.e. float).
  // Warning: This function is lossy, i.e. precision is lost when converting
  // BigInt -> number.
  // Note: BigInt -> number conversion is relatively slow.
  static toSeconds(t: time): number {
    return Number(t) / TIME_UNITS_PER_SEC;
  }

  // Convert milliseconds (number) to a time value.
  // Note: number -> BigInt conversion is relatively slow.
  static fromMillis(millis: number): time {
    return Time.fromRaw(BigInt(Math.floor(millis * TIME_UNITS_PER_MILLISEC)));
  }

  // Convert time value to milliseconds and return as a number (i.e. float).
  // Warning: This function is lossy, i.e. precision is lost when converting
  // BigInt -> number.
  // Note: BigInt -> number conversion is relatively slow.
  static toMillis(t: time): number {
    return Number(t) / TIME_UNITS_PER_MILLISEC;
  }

  // Convert a Date object to a time value, given an offset from the unix epoch.
  // Note: number -> BigInt conversion is relatively slow.
  static fromDate(d: Date, offset: duration): time {
    const millis = d.getTime();
    const t = Time.fromMillis(millis);
    return Time.add(t, offset);
  }

  // Convert time value to a Date object, given an offset from the unix epoch.
  // Warning: This function is lossy, i.e. precision is lost when converting
  // BigInt -> number.
  // Note: BigInt -> number conversion is relatively slow.
  static toDate(t: time, offset: duration): Date {
    const timeSinceEpoch = Time.sub(t, offset);
    const millis = Time.toMillis(timeSinceEpoch);
    return new Date(millis);
  }

  // Find the closest previous midnight for a given time value.
  static quantWholeDaysUTC(time: time, realtimeOffset: duration): time {
    const date = Time.toDate(time, realtimeOffset);

    const nearestWholeDay = new Date(Date.UTC(
        date.getUTCFullYear(),
        date.getUTCMonth(),
        date.getUTCDate(),
        ));

    return Time.fromDate(nearestWholeDay, realtimeOffset);
  }

  static add(t: time, d: duration): time {
    return Time.fromRaw(t + d);
  }

  static sub(t: time, d: duration): time {
    return Time.fromRaw(t - d);
  }

  static diff(a: time, b: time): duration {
    return a - b;
  }

  static min(a: time, b: time): time {
    return Time.fromRaw(BigintMath.min(a, b));
  }

  static max(a: time, b: time): time {
    return Time.fromRaw(BigintMath.max(a, b));
  }

  static quantFloor(a: time, b: duration): time {
    return Time.fromRaw(BigintMath.quantFloor(a, b));
  }

  static quantCeil(a: time, b: duration): time {
    return Time.fromRaw(BigintMath.quantCeil(a, b));
  }

  static quant(a: time, b: duration): time {
    return Time.fromRaw(BigintMath.quant(a, b));
  }

  // Format time as seconds.
  static formatSeconds(time: time): string {
    return Time.toSeconds(time).toString() + ' s';
  }

  static toTimecode(time: time): Timecode {
    return new Timecode(time);
  }
}

export class Duration {
  // The min and max possible duration values - durations can be negative.
  static MIN = BigintMath.INT64_MIN;
  static MAX = BigintMath.INT64_MAX;
  static ZERO = 0n;

  static min(a: duration, b: duration): duration {
    return BigintMath.min(a, b);
  }

  static max(a: duration, b: duration): duration {
    return BigintMath.max(a, b);
  }

  static fromMillis(millis: number) {
    return BigInt(Math.floor((millis / 1e3) * TIME_UNITS_PER_SEC));
  }

  // Convert time to seconds as a number.
  // Use this function with caution. It loses precision and is slow.
  static toSeconds(d: duration) {
    return Number(d) / TIME_UNITS_PER_SEC;
  }

  // Print duration as as human readable string - i.e. to only a handful of
  // significant figues.
  // Use this when readability is more desireable than precision.
  // Examples: 1234 -> 1.23ns
  //           123456789 -> 123ms
  //           123,123,123,123,123 -> 34h 12m
  //           1,000,000,023 -> 1 s
  //           1,230,000,023 -> 1.2 s
  static humanise(dur: duration) {
    const sec = Duration.toSeconds(dur);
    const units = ['s', 'ms', 'us', 'ns'];
    const sign = Math.sign(sec);
    let n = Math.abs(sec);
    let u = 0;
    while (n < 1 && n !== 0 && u < units.length - 1) {
      n *= 1000;
      u++;
    }
    return `${sign < 0 ? '-' : ''}${Math.round(n * 10) / 10}${units[u]}`;
  }

  // Print duration with absolute precision.
  static format(duration: duration): string {
    let result = '';
    if (duration < 1) return '0s';
    const unitAndValue: [string, bigint][] = [
      ['h', 3_600_000_000_000n],
      ['m', 60_000_000_000n],
      ['s', 1_000_000_000n],
      ['ms', 1_000_000n],
      ['us', 1_000n],
      ['ns', 1n],
    ];
    unitAndValue.forEach(([unit, unitSize]) => {
      if (duration >= unitSize) {
        const unitCount = duration / unitSize;
        result += unitCount.toLocaleString() + unit + ' ';
        duration = duration % unitSize;
      }
    });
    return result.slice(0, -1);
  }
}

// This class takes a time and converts it to a set of strings representing a
// time code where each string represents a group of time units formatted with
// an appropriate number of leading zeros.
export class Timecode {
  public readonly sign: string;
  public readonly days: string;
  public readonly hours: string;
  public readonly minutes: string;
  public readonly seconds: string;
  public readonly millis: string;
  public readonly micros: string;
  public readonly nanos: string;

  constructor(time: time) {
    this.sign = time < 0 ? '-' : '';

    const absTime = BigintMath.abs(time);

    const days = (absTime / 86_400_000_000_000n);
    const hours = (absTime / 3_600_000_000_000n) % 24n;
    const minutes = (absTime / 60_000_000_000n) % 60n;
    const seconds = (absTime / 1_000_000_000n) % 60n;
    const millis = (absTime / 1_000_000n) % 1_000n;
    const micros = (absTime / 1_000n) % 1_000n;
    const nanos = absTime % 1_000n;

    this.days = days.toString();
    this.hours = hours.toString().padStart(2, '0');
    this.minutes = minutes.toString().padStart(2, '0');
    this.seconds = seconds.toString().padStart(2, '0');
    this.millis = millis.toString().padStart(3, '0');
    this.micros = micros.toString().padStart(3, '0');
    this.nanos = nanos.toString().padStart(3, '0');
  }

  // Get the upper part of the timecode formatted as: [-]DdHH:MM:SS.
  get dhhmmss(): string {
    const days = this.days === '0' ? '' : `${this.days}d`;
    return `${this.sign}${days}${this.hours}:${this.minutes}:${this.seconds}`;
  }

  // Get the subsecond part of the timecode formatted as: mmm uuu nnn.
  // The "space" char is configurable but defaults to a normal space.
  subsec(spaceChar: string = ' '): string {
    return `${this.millis}${spaceChar}${this.micros}${spaceChar}${this.nanos}`;
  }

  // Formats the entire timecode to a string.
  toString(spaceChar: string = ' '): string {
    return `${this.dhhmmss}.${this.subsec(spaceChar)}`;
  }
}


export function currentDateHourAndMinute(): string {
  const date = new Date();
  return `${date.toISOString().substr(0, 10)}-${date.getHours()}-${
      date.getMinutes()}`;
}

// Create a Time value from an arbitrary SQL value.


// Represents a half-open interval of time in the form [start, end).
// E.g. interval contains all time values which are >= start and < end.
export interface Span<TimeT, DurationT = TimeT> {
  get start(): TimeT;
  get end(): TimeT;
  get duration(): DurationT;
  get midpoint(): TimeT;
  contains(span: TimeT|Span<TimeT, DurationT>): boolean;
  intersectsInterval(span: Span<TimeT, DurationT>): boolean;
  intersects(a: TimeT, b: TimeT): boolean;
  equals(span: Span<TimeT, DurationT>): boolean;
  add(offset: DurationT): Span<TimeT, DurationT>;
  pad(padding: DurationT): Span<TimeT, DurationT>;
}

export class TimeSpan implements Span<time, duration> {
  static readonly ZERO = new TimeSpan(Time.ZERO, Time.ZERO);
  readonly start: time;
  readonly end: time;

  constructor(start: time, end: time) {
    assertTrue(
        start <= end,
        `Span start [${start}] cannot be greater than end [${end}]`);
    this.start = start;
    this.end = end;
  }

  get duration(): duration {
    return this.end - this.start;
  }

  get midpoint(): time {
    return Time.fromRaw((this.start + this.end) / 2n);
  }

  contains(x: time|Span<time, duration>): boolean {
    if (typeof x === 'bigint') {
      return this.start <= x && x < this.end;
    } else {
      return this.start <= x.start && x.end <= this.end;
    }
  }

  intersectsInterval(span: Span<time, duration>): boolean {
    return !(span.end <= this.start || span.start >= this.end);
  }

  intersects(start: time, end: time): boolean {
    return !(end <= this.start || start >= this.end);
  }

  equals(span: Span<time, duration>): boolean {
    return this.start === span.start && this.end === span.end;
  }

  add(x: duration): Span<time, duration> {
    return new TimeSpan(Time.add(this.start, x), Time.add(this.end, x));
  }

  pad(padding: duration): Span<time, duration> {
    return new TimeSpan(
        Time.sub(this.start, padding), Time.add(this.end, padding));
  }
}

// Print the date only for a given date in ISO format.
export function toISODateOnly(date: Date) {
  const year = date.getUTCFullYear();
  const month = String(date.getUTCMonth() + 1).padStart(2, '0');
  const day = String(date.getUTCDate()).padStart(2, '0');

  return `${year}-${month}-${day}`;
}
