// Copyright (C) 2023 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 {assertExists} from './logging';
import {exists} from './utils';

export type PathKey = string|number;
export type Path = PathKey[];

/**
 * Gets the |value| at a |path| of |object|. If a portion of the path doesn't
 * exist, |undefined| is returned.
 *
 * Example:
 * const obj = {
 *   a: [
 *     {b: 'c'},
 *     {d: 'e', f: 123},
 *   ],
 * };
 * getPath(obj, ['a']) -> [{b: 'c'}, {d: 'e', f: 123}]
 * getPath(obj, ['a', 1]) -> {d: 'e', f: 123}
 * getPath(obj, ['a', 1, 'd']) -> 'e'
 * getPath(obj, ['g']) -> undefined
 * getPath(obj, ['g', 'h']) -> undefined
 *
 * Note: This is an appropriate use of `any`, as we are knowingly getting fast
 * and loose with the type system in this function: it's basically JavaScript.
 * Attempting to pretend it's anything else would result in superfluous type
 * assertions which would serve no benefit.
 */
// eslint-disable-next-line @typescript-eslint/no-explicit-any
export function getPath<T>(obj: any, path: Path): T|undefined {
  let x = obj;
  for (const node of path) {
    if (x === undefined) return undefined;
    x = x[node];
  }
  return x;
}

/**
 * Sets the |value| at |path| of |object|. If the final node of the path doesn't
 * exist, the value will be created. Otherwise, TypeError is thrown.
 *
 * Example:
 * const obj = {
 *   a: [
 *     {b: 'c'},
 *     {d: 'e', f: 123},
 *   ],
 * };
 * setPath(obj, ['a'], 'foo') -> {a: 'foo'}
 * setPath(obj, ['a', 1], 'foo') -> {a: [{b: 'c'}, 'foo']}
 * setPath(obj, ['g'], 'foo') -> {a: [...], g: 'foo'}
 * setPath(obj, ['g', 'h'], 'foo') -> TypeError!
 */
// eslint-disable-next-line @typescript-eslint/no-explicit-any
export function setPath<T>(obj: any, path: Path, value: T): void {
  const pathClone = [...path];
  let o = obj;
  while (pathClone.length > 1) {
    const p = assertExists(pathClone.shift());
    o = o[p];
  }

  const p = pathClone.shift();
  if (!exists(p)) {
    throw TypeError('Path array is empty');
  }
  o[p] = value;
}

export function shallowEquals(a: unknown, b: unknown) {
  if (a === b) {
    return true;
  }
  if (a === undefined || b === undefined) {
    return false;
  }
  if (a === null || b === null) {
    return false;
  }
  const objA = a as {[_: string]: {}};
  const objB = b as {[_: string]: {}};
  for (const key of Object.keys(objA)) {
    if (objA[key] !== objB[key]) {
      return false;
    }
  }
  for (const key of Object.keys(objB)) {
    if (objA[key] !== objB[key]) {
      return false;
    }
  }
  return true;
}

export function isString(s: unknown): s is string {
  return typeof s === 'string' || s instanceof String;
}

// Given a string enum |enum|, check that |value| is a valid member of |enum|.
export function isEnumValue<T extends {}>(
  enm: T, value: unknown): value is T[keyof T] {
  return Object.values(enm).includes(value);
}
