// Copyright (C) 2019 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 {hsl} from 'color-convert';

import {hash} from '../common/hash';
import {cachedHsluvToHex} from '../frontend/hsluv_cache';

export interface Color {
  c: string;
  h: number;
  s: number;
  l: number;
  a?: number;
}

const MD_PALETTE: Color[] = [
  {c: 'red', h: 4, s: 90, l: 58},
  {c: 'pink', h: 340, s: 82, l: 52},
  {c: 'purple', h: 291, s: 64, l: 42},
  {c: 'deep purple', h: 262, s: 52, l: 47},
  {c: 'indigo', h: 231, s: 48, l: 48},
  {c: 'blue', h: 207, s: 90, l: 54},
  {c: 'light blue', h: 199, s: 98, l: 48},
  {c: 'cyan', h: 187, s: 100, l: 42},
  {c: 'teal', h: 174, s: 100, l: 29},
  {c: 'green', h: 122, s: 39, l: 49},
  {c: 'light green', h: 88, s: 50, l: 53},
  {c: 'lime', h: 66, s: 70, l: 54},
  {c: 'amber', h: 45, s: 100, l: 51},
  {c: 'orange', h: 36, s: 100, l: 50},
  {c: 'deep orange', h: 14, s: 100, l: 57},
  {c: 'brown', h: 16, s: 25, l: 38},
  {c: 'blue gray', h: 200, s: 18, l: 46},
  {c: 'yellow', h: 54, s: 100, l: 62},
];

export const GRAY_COLOR: Color = {
  c: 'grey',
  h: 0,
  s: 0,
  l: 62,
};

// A piece of wisdom from a long forgotten blog post: "Don't make
// colors you want to change something normal like grey."
export const UNEXPECTED_PINK_COLOR: Color = {
  c: '#ff69b4',
  h: 330,
  s: 1.0,
  l: 0.706,
};

export function hueForCpu(cpu: number): number {
  return (128 + (32 * cpu)) % 256;
}

const DESAT_RED: Color = {
  c: 'desat red',
  h: 3,
  s: 30,
  l: 49,
};
const DARK_GREEN: Color = {
  c: 'dark green',
  h: 120,
  s: 44,
  l: 34,
};
const LIME_GREEN: Color = {
  c: 'lime green',
  h: 75,
  s: 55,
  l: 47,
};
const TRANSPARENT_WHITE: Color = {
  c: 'white',
  h: 0,
  s: 1,
  l: 97,
  a: 0.55,
};
const ORANGE: Color = {
  c: 'orange',
  h: 36,
  s: 100,
  l: 50,
};
const INDIGO: Color = {
  c: 'indigo',
  h: 231,
  s: 48,
  l: 48,
};

export function colorForState(state: string): Readonly<Color> {
  if (state === 'Running') {
    return DARK_GREEN;
  } else if (state.startsWith('Runnable')) {
    return LIME_GREEN;
  } else if (state.includes('Uninterruptible Sleep')) {
    if (state.includes('non-IO')) {
      return DESAT_RED;
    }
    return ORANGE;
  } else if (state.includes('Sleeping') || state.includes('Idle')) {
    return TRANSPARENT_WHITE;
  }
  return INDIGO;
}

export function textColorForState(stateCode: string): string {
  const background = colorForState(stateCode);
  return background.l > 80 ? '#404040' : '#fff';
}

export function colorForString(identifier: string): Color {
  const colorIdx = hash(identifier, MD_PALETTE.length);
  return Object.assign({}, MD_PALETTE[colorIdx]);
}

export function colorForTid(tid: number): Color {
  return colorForString(tid.toString());
}

export function colorForThread(thread?: {pid?: number, tid: number}): Color {
  if (thread === undefined) {
    return Object.assign({}, GRAY_COLOR);
  }
  const tid = thread.pid ? thread.pid : thread.tid;
  return colorForTid(tid);
}

// 40 different random hues 9 degrees apart.
export function randomColor(): string {
  const hue = Math.floor(Math.random() * 40) * 9;
  return '#' + hsl.hex([hue, 90, 30]);
}

// Chooses a color uniform at random based on hash(sliceName).  Returns [hue,
// saturation, lightness].
//
// Prefer converting this to an RGB color using hsluv, not the browser's
// built-in vanilla HSL handling.  This is because this function chooses
// hue/lightness uniform at random, but HSL is not perceptually uniform.  See
// https://www.boronine.com/2012/03/26/Color-Spaces-for-Human-Beings/.
//
// If isSelected, the color will be particularly dark, making it stand out.
export function hslForSlice(
    sliceName: string, isSelected: boolean|null): [number, number, number] {
  const hue = hash(sliceName, 360);
  // Saturation 100 would give the most differentiation between colors, but it's
  // garish.
  const saturation = 80;
  const lightness = isSelected ? 30 : hash(sliceName + 'x', 40) + 40;
  return [hue, saturation, lightness];
}

// Lightens the color for thread slices to represent wall time.
export function colorForThreadIdleSlice(
    hue: number,
    saturation: number,
    lightness: number,
    isSelected: boolean|null): string {
  // Increase lightness by 80% when selected and 40% otherwise,
  // without exceeding 88.
  let newLightness = isSelected ? lightness * 1.8 : lightness * 1.4;
  newLightness = Math.min(newLightness, 88);
  return cachedHsluvToHex(hue, saturation, newLightness);
}

export function colorToStr(color: Color) {
  if (color.a !== undefined) {
    return `hsla(${color.h}, ${color.s}%, ${color.l}%, ${color.a})`;
  }
  return `hsl(${color.h}, ${color.s}%, ${color.l}%)`;
}

export function colorCompare(x: Color, y: Color) {
  return (x.h - y.h) || (x.s - y.s) || (x.l - y.l);
}
