// 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 getLatestMidnight(time: time, offset: duration): time {
    const date = Time.toDate(time, offset);
    const floorDay = new Date(
      Date.UTC(date.getUTCFullYear(), date.getUTCMonth(), date.getUTCDate()),
    );

    return Time.fromDate(floorDay, offset);
  }

  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;

  // Cast a bigint to a |duration|. Supports potentially |undefined| values.
  // I.e. it performs the following conversions:
  // - `bigint` -> `duration`
  // - `bigint|undefined` -> `duration|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 duration value". It's
  // up to the caller to ensure the value is in the correct units.
  //
  // If you're reaching for this function after doing some maths on a |duration|
  // value and it's decayed to a |bigint| consider using the static math methods
  // in |duration| instead, as they will do the appropriate casting for you.
  static fromRaw(v: bigint): duration;
  static fromRaw(v?: bigint): duration | undefined;
  static fromRaw(v?: bigint): duration | undefined {
    return v as duration | undefined;
  }

  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): string {
    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);
  }

  static formatSeconds(dur: duration): string {
    return Duration.toSeconds(dur).toString() + ' s';
  }
}

// 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;
  }

  static fromTimeAndDuration(start: time, duration: duration): TimeSpan {
    return new TimeSpan(start, Time.add(start, duration));
  }

  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}`;
}
