import { AnyARecord } from "dns";
import { BackendError, ITypedBackendResponse } from "./backend-response";
import { VTX_ERRORS } from "@vertikalx/vtx-core-common";


export type checkerFn = (response:any)=>boolean;

const Logger = {
  log:(msg:string)=>{
    //console.log(msg)
  }
};

export function buildResponse<T>(response:any, rootProperty:string, checker: checkerFn):ITypedBackendResponse<T>{
    const retValue:ITypedBackendResponse<T> = {}

    //console.log("=========== BEGIN buildResponse =============");
    //console.log(JSON.stringify(response, null, 2));

    //console.log("=========== END buildResponse =============");
      
      if (checker(response)){

        //Logger.log('checker 1');
        try {
          retValue.data = response[rootProperty] as T;
        } catch (casterr) {
          Logger.log('Error trying to cast to return type');
          retValue.error = {
            httpStatus:500,
            code:VTX_ERRORS.VTX_SERVER_ERROR.code,
            message:"Error: Obtained incorrect data from Backend"
          };
          retValue.rawErrors = [
            {
              data:response,
              error:casterr
            }
          ];          
        }
  
      } else if (response?.errors) {        

        //Logger.log('checker 2');
        if (Array.isArray(response.errors)) {
          retValue.rawErrors = response.errors;
        } else {
          retValue.rawErrors = [response.errors];
        }
  
      } else if (response?.error) {
        //Logger.log('checker 3');
  
        if (Array.isArray(response.error)) {
          retValue.rawErrors = response.error;
        } else {
          retValue.rawErrors = [response.error];
        }
  
      } else if (checker(response?.data)) {
        //Logger.log('checker 4');
  
        try {
          retValue.data = response.data[rootProperty] as T;
        } catch (casterr) {
          Logger.log('Error trying to cast to return type');
          
          retValue.error = {
            httpStatus:500,
            code:VTX_ERRORS.VTX_SERVER_ERROR.code,
            message:"Error: Obtained incorrect data from Backend"
          };
          retValue.rawErrors = [
            {
              data:response.data,
              error:casterr
            }
          ];    

        }
      } else {
        //Logger.log('checker 5');
        retValue.error = {
          httpStatus:500,
          code:VTX_ERRORS.VTX_SERVER_ERROR.code,
          message:"Error: Obtained incorrect data from Backend"
        };
        retValue.rawErrors = ['Error: Obtained incorrect data from Backend'];
      }
  

    Logger.log('buildResponse retValue:');
    Logger.log(JSON.stringify(retValue,null,2));

    return retValue;
}
export function buildErrorResponse<T>(error:any):ITypedBackendResponse<T>{

  //Logger.log("=========== BEGIN buildErrorResponse received =============");
  //Logger.log(JSON.stringify(error, null, 2));

  //Logger.log("=========== END buildErrorResponse received =============");

  const retValue:ITypedBackendResponse<T> = {}
  if (error.errors){

    if (Array.isArray(error.errors)){
      retValue.rawErrors = error.errors;

    }else{
      retValue.rawErrors = [error.errors];
      
    }

  }else{
    if (Array.isArray(error)){
      retValue.rawErrors = error;
    }else{
      retValue.rawErrors = [error];
    }    
  }

  retValue.error = extractError(retValue.rawErrors );

  //Logger.log("=========== BEGIN buildErrorResponse returned =============");
  //Logger.log(JSON.stringify(retValue, null, 2));

  //Logger.log("=========== END buildErrorResponse returned =============");

    
  return retValue;
}
function extractError(rawErrors: any[]|undefined): BackendError {
  
  let retValue:BackendError = {
    httpStatus:500,
    code:VTX_ERRORS.VTX_SERVER_ERROR.code,
    message:VTX_ERRORS.VTX_SERVER_ERROR.description 
  };

  if (! rawErrors || rawErrors.length <= 0){    
    return retValue;
  }

  let theError:any = rawErrors.find( e => {

      if (e.extensions && e.extensions.type === "VtxError"){
        return true;
      }
      return false;
  });

  if (theError){
    retValue = {
      httpStatus:theError?.extensions?.httpStatus ?? 500,
      code: theError?.extensions?.vtxError?.code ?? VTX_ERRORS.VTX_SERVER_ERROR.code,
      message: theError?.extensions?.vtxError?.description  ?? VTX_ERRORS.VTX_SERVER_ERROR.description 
    }
  }

  return retValue;
  

}

