
/**
 * Describe a variable that can only contains as data an array of number
 */
export interface MeasurementVariable<
  DataType extends DoubleArray = DoubleArray,
> {
  /**
   * Unit of the data in the column
   * @TJS-examples ["Pa", "kg"]
   */
  units?: string;
  /**
   * Long name of the column
   *@TJS-examples ["absolute pressure"]
   */
  label: string;
  /**
   *
   */
  isDependent?: boolean;
  /**
   * An array containing numerical data
   */
  data: DataType;
  /** One letter that allows to define the variable */
  symbol?: OneLetter;
  /** If defined contain the minimal value of the data */
  min?: number;
  /** If defined contain the maximal value of the data */
  max?: number;
  /**
   * If defined indicates if the data series is monotonic.
   * `1` means that the data is increasing.
   * `-1` means that the data is decreasing.
   * `0` means that the data is not monotonic.
   */
  isMonotonic?: -1 | 0 | 1;
}


export interface MeasurementXY<DataType extends DoubleArray = DoubleArray> {
  /**
   * A unique identifier for the measurement, preferably a UUID.
   */
  id?: string;
  /**
   * Variables containing the data of the measurement.
   * It must contain at least the variable `x` and `y`
   */
  variables: MeasurementXYVariables<DataType>;
  /**
   * Title of the experiment. Often contains the sample code
   */
  title?: string;
  /**
   * May contain the type of data. This is practical when you have a bunch of data
   * of different types
   */
  dataType?: string;
  settings?: {
    instrument?: Instrument;
    [key: string]: any;
  };
  meta?: Record<string, any>;
  derived?: Record<string, any>;
}


export interface MeasurementXYVariables<
  DataType extends DoubleArray = DoubleArray,
> {
  a?: MeasurementVariable<DataType>;
  b?: MeasurementVariable<DataType>;
  c?: MeasurementVariable<DataType>;
  d?: MeasurementVariable<DataType>;
  e?: MeasurementVariable<DataType>;
  f?: MeasurementVariable<DataType>;
  g?: MeasurementVariable<DataType>;
  h?: MeasurementVariable<DataType>;
  i?: MeasurementVariable<DataType>;
  j?: MeasurementVariable<DataType>;
  k?: MeasurementVariable<DataType>;
  l?: MeasurementVariable<DataType>;
  m?: MeasurementVariable<DataType>;
  n?: MeasurementVariable<DataType>;
  o?: MeasurementVariable<DataType>;
  p?: MeasurementVariable<DataType>;
  q?: MeasurementVariable<DataType>;
  r?: MeasurementVariable<DataType>;
  s?: MeasurementVariable<DataType>;
  t?: MeasurementVariable<DataType>;
  u?: MeasurementVariable<DataType>;
  v?: MeasurementVariable<DataType>;
  w?: MeasurementVariable<DataType>;
  x: MeasurementVariable<DataType>;
  y: MeasurementVariable<DataType>;
  z?: MeasurementVariable<DataType>;
}
export interface NmrData1D {
  x: Float64Array;
  re: Float64Array;
  im?: Float64Array;
}
export interface NmrData2DContent {
  z: Float64Array[];
  minZ: number;
  maxZ: number;
  minY: number;
  maxY: number;
  minX: number;
  maxX: number;
}

export type NmrData2D = NmrData2DFid | NmrData2DFt;

export interface NmrData2DFidReIm {
  re: NmrData2DContent;
  im: NmrData2DContent;
}

export interface NmrData2DFid {
  re: NmrData2DContent;
  im?: NmrData2DContent;
}

export interface NmrData2DFt {
  rr: NmrData2DContent;
  ri?: NmrData2DContent;
  ir?: NmrData2DContent;
  ii?: NmrData2DContent;
}

export interface ICPDilution {
  factor?: number;
  solvent?: string;
}

export interface ICPResult {
  element: string;
  wavelength?: Value;
  experimentalConcentration?: Value;
  dilution?: ICPDilution;
  sampleConcentration?: Value;
}

export interface DataXY<DataType extends NumberArray = NumberArray> {
  /**
   * Array of numbers on x-axis
   */
  x: DataType;
  /**
   * Array of numbers on y-axis
   */
  y: DataType;
}

/** The instrument with which a spectrum was measured.
 *  CHMO: 0000998
 */
export interface Instrument {
  /** The name of the instrument.
   * @TJS-examples ["BELSORP MAX II"]
   */
  model: string;
  /** The name of the instrument manufacturer
   * @TJS-examples ["Microtrac Retsch GmbH", "Bruker"]
   */
  manufacturer: string;
  /** The INTERNAL serial number of the instrument, e.g., the inventory number of the instrument in a university
   * @TJS-examples ["B105863"]
   */
  serialNumber?: string;
  /** Stock Keeping Unit (SKU), i.e. a merchant-specific identifier for a product or service, or the product to which the offer refers.
   * @TJS-examples ["345"]
   */
  sku?: string;
  /** The name of the software and the version number
   * @TJS-examples ["BELMaster™ 7"]
   */
  software?: Software;
  location?: Location;
}
/**
 * Many libraries use a logger interface to log information about the processing.
 * This logger is expected to be compatible not only with the one from the `pino` library but
 * also with the default `console`.
 * This means that the library can output logs by default to the console and the user can
 * replace it with a custom logger that implements this interface.
 */
export interface LightLogger {
  trace(obj: Record<string, unknown>, message: string): void;
  trace(message: string): void;
  trace(error: Error): void;
  trace(value: unknown, message?: string): void;

  debug(obj: Record<string, unknown>, message: string): void;
  debug(message: string): void;
  debug(error: Error): void;
  debug(value: unknown, message?: string): void;

  info(obj: Record<string, unknown>, message: string): void;
  info(message: string): void;
  info(error: Error): void;
  info(value: unknown, message?: string): void;

  warn(obj: Record<string, unknown>, message: string): void;
  warn(message: string): void;
  warn(error: Error): void;
  warn(value: unknown, message?: string): void;

  error(obj: Record<string, unknown>, message: string): void;
  error(message: string): void;
  error(error: Error): void;
  error(value: unknown, message?: string): void;
}
export type BinaryData = ArrayBuffer | Uint8Array;
export interface OCLMolecule {
  idCode: string;
  coordinates?: string;
  index?: number[]; // should be 16 numbers in fact
}
/**
 * case we may have a text, ArrayBuffer or Uint8Array
 * This type is used by the package `ensure-string` to ensure that the data
 * is actually a string.
 * This is very useful in the packages like `jcampconverter` or `xy-parser`
 */

export type TextData = string | BinaryData;
/**
 * A type that allows one uppercase or lowercase letter
 */
export type OneUpperCase =
  | 'A'
  | 'B'
  | 'C'
  | 'D'
  | 'E'
  | 'F'
  | 'G'
  | 'H'
  | 'I'
  | 'J'
  | 'K'
  | 'L'
  | 'M'
  | 'N'
  | 'O'
  | 'P'
  | 'Q'
  | 'R'
  | 'S'
  | 'T'
  | 'U'
  | 'V'
  | 'W'
  | 'X'
  | 'Y'
  | 'Z';
/**
 * Defines 2 limits as numbers
 */

export interface FromTo {
  from: number;
  to: number;
}
export interface PeakXYWidth {
  x: number;
  y: number;
  width: number;
}
/**
 * A type that allows one uppercase or lowercase letter
 */
export type OneLetter =
  | 'a'
  | 'b'
  | 'c'
  | 'd'
  | 'e'
  | 'f'
  | 'g'
  | 'h'
  | 'i'
  | 'j'
  | 'k'
  | 'l'
  | 'm'
  | 'n'
  | 'o'
  | 'p'
  | 'q'
  | 'r'
  | 's'
  | 't'
  | 'u'
  | 'v'
  | 'w'
  | 'x'
  | 'y'
  | 'z'
  | 'A'
  | 'B'
  | 'C'
  | 'D'
  | 'E'
  | 'F'
  | 'G'
  | 'H'
  | 'I'
  | 'J'
  | 'K'
  | 'L'
  | 'M'
  | 'N'
  | 'O'
  | 'P'
  | 'Q'
  | 'R'
  | 'S'
  | 'T'
  | 'U'
  | 'V'
  | 'W'
  | 'X'
  | 'Y'
  | 'Z';
/**
 * In order to store an array of numbers we prefer to either use native javascript
 * arrays or to use Float64Array
 */

export type DoubleArray = number[] | Float64Array;
/**
 * A type that allows one uppercase or lowercase letter
 */
export type OneLowerCase =
  | 'a'
  | 'b'
  | 'c'
  | 'd'
  | 'e'
  | 'f'
  | 'g'
  | 'h'
  | 'i'
  | 'j'
  | 'k'
  | 'l'
  | 'm'
  | 'n'
  | 'o'
  | 'p'
  | 'q'
  | 'r'
  | 's'
  | 't'
  | 'u'
  | 'v'
  | 'w'
  | 'x'
  | 'y'
  | 'z';
/**
 *  Quantity that is defined as range, e.g., melting point
 */
export interface Range {
  /** The lower value of some  characteristic or property.*/
  min: number;
  /** The upper value of some characteristic or property.*/
  max: number;
  /** */
  precision?: number;
  /**A string or text indicating the unit of measurement. Useful if you cannot provide a standard unit code for unitCode. */
  units?: string;
}
export interface PointXY {
  a?: number;
  b?: number;
  c?: number;
  d?: number;
  e?: number;
  f?: number;
  g?: number;
  h?: number;
  i?: number;
  j?: number;
  k?: number;
  l?: number;
  m?: number;
  n?: number;
  o?: number;
  p?: number;
  q?: number;
  r?: number;
  s?: number;
  t?: number;
  u?: number;
  v?: number;
  w?: number;
  x: number;
  y: number;
  z?: number;
}
export type NumberArray =
  | number[]
  | Int8Array
  | Uint8Array
  | Uint8ClampedArray
  | Int16Array
  | Uint16Array
  | Int32Array
  | Uint32Array
  | Float32Array
  | Float64Array;
/** Value with units as https://schema.org/Value */
export interface Value {
  /** The value of the quantitative value or property value node.
   * @TJS-examples [0, 1000, 1345.24456, -10, -100]
   */
  value: number;
  /** */
  precision?: number;
  /**A string or text indicating the unit of measurement. The unit could be validated in the input form based on the UN/CEFACT Common Code list */
  units?: string;
}
/**Describes the location of some object. */
export interface Location {
  /** Name of the institution
   * @TJS-examples ["EPFL", "Heriot-Watt University"]
   */
  entity: string;
  /** Name or code of the building
   * @TJS-examples ["I17", "Main building"]
   */
  building?: string;
  /**Name or code of the room in which the object is localized
   * @TJS-examples ["1 B3", "Lab 1"]
   */
  room?: string;
  /** Internal code that is used to identify the location
   * @TJS-examples ["I17 1 B3"]
   */
  code: string;
}
export interface Software {
  /** Version of the software instance.
   * @TJS-examples ['v0.0.1', 'rev111']
   */
  version?: string;
  /**    The name of the item.
   * @TJS-examples ['tga-analysis', 'ChemDraw']
   */
  name: string;
  /**    A description of the item. */
  description?: string;
  /**    If the file can be downloaded, URL to download the binary
   * @TJS-examples ['https://github.com/cheminfo/tga-spectrum/releases/tag/v0.16.0']
   */
  url?: string;
}

/**
 * Many libraries use a logger interface to log information about the processing.
 * This logger is expected to be compatible with the one from the `pino` library
 */
export interface Logger extends LightLogger {
  child(bindings?: Record<string, any>): Logger;

  fatal(obj: Record<string, unknown>, message: string): void;
  fatal(message: string): void;
  fatal(error: Error): void;
  fatal(value: unknown, message?: string): void;
}
export type NumberMatrix =
  | number[][]
  | Int8Array[]
  | Uint8Array[]
  | Uint8ClampedArray[]
  | Int16Array[]
  | Uint16Array[]
  | Int32Array[]
  | Uint32Array[]
  | Float32Array[]
  | Float64Array[];
/**
 * Defines 2 limits as numbers
 */

export interface FromToXY {
  from: PointXY;
  to: PointXY;
}
