import {Request} from '@prodress/pdr2com';

export interface DataTypeConversion {
  string: () => string;
  integer: () => number;
  float: () => number;
  date: () => Date | null;
  date_time: () => Date | null;
}

export interface ResponseObject {
  [key: string]: ReturnType<DataTypeConversion[keyof DataTypeConversion]>;
}

export type ResponseTupel = [string, keyof DataTypeConversion];

export type RequestTupel = {
  [K in keyof DataTypeConversion]: [K, NonNullable<ReturnType<DataTypeConversion[K]>>];
}[keyof DataTypeConversion];

export class ProdressRequest extends Request {
  public constructor(db: string, handler: string, action: string) {
    super(
      {
        interneProtokollVersion: 1,
        benutzer: '',
        passwort: '',
        programm: handler,
        datenbank: db,
        typ: action,
        transaktionsId: 0,
        protokoll: 0,
        fehlerCode: 0,
        fehlerIsPermanent: 0,
        fehlerText: '',
      },
      Buffer.alloc(0),
      {
        rechenzeit: 0,
        verwendeUtf8: true,
        maximalePaketgröße: 0,
      },
    );
  }

  /**
   * writes entries based on the provided requestTupelList into the request
   * @param requestTupelList
   */
  public writeEntries(requestTupelList: RequestTupel[]): void {
    for (const tupel of requestTupelList) {
      this.writeEntry(tupel);
    }
  }

  /**
   * writes an entry based on the provided requestTupel into the request
   * @param requestTupel
   */
  public writeEntry(requestTupel: RequestTupel): void {
    const [type, value] = requestTupel;
    switch (type) {
      case 'string':
        this.schreibeText(value);
        break;
      case 'integer':
        this.schreibeGanzzahl(value);
        break;
      case 'float':
        this.schreibeDezimalzahl(value);
        break;
      case 'date':
        this.schreibeDatum(value);
        break;
      case 'date_time':
        this.schreibeDatumMitZeit(value);
        break;
    }
  }
}
