import { codeBlock , ODataVersion } from '@sap-cloud-sdk/util' ; import voca from 'voca' ; import { VdmEntity , VdmServiceMetadata } from '../../vdm-types' ; import { matchEntity } from '../entity-api/match-entity' ; import { getGenericTypes , getGenericTypesWithDefault } from '../de-serializers-generic-types' ; export function serviceBuilder ( serviceName , oDataVersion ) { return codeBlock `
  export function ${ voca . decapitalize ( serviceName ) }<${ getGenericTypesWithDefault ( oDataVersion ) }>(
  deSerializers: Partial<DeSerializers<${ getGenericTypes ( oDataVersion ) }>> = defaultDeSerializers as any
  ):${ serviceName }<DeSerializers<${ getGenericTypes ( oDataVersion ) }>>  
  {
  return new ${ serviceName }(mergeDefaultDeSerializersWith(deSerializers))
  }
  ` ; } export function serviceClass ( service ) { return codeBlock `export class ${ service . className }<DeSerializersT extends DeSerializers = DefaultDeSerializers> {
    private apis: Record<string, any> = {};
    private deSerializers: DeSerializersT;

    constructor(deSerializers: DeSerializersT) {
      this.deSerializers = deSerializers;
    }

    private initApi(key: string, ctor: new (...args: any[]) => any): any {
      if (!this.apis[key]) {
        this.apis[key] = new ctor(this.deSerializers);
      }
      return this.apis[key];
    }

    ${ service . entities . map ( entity => getEntityApiFunction ( entity , service ) ) . join ( '\n\n' ) }
    
    ${ getActionFunctionImports ( service , 'functionImports' ) }
    
    ${ getActionFunctionImports ( service , 'actionImports' ) }
    
    ${ getBatch ( ) }
  }` ; } function getActionFunctionImports ( service , type ) { if ( service [ type ] === undefined || service [ type ] ! . length === 0 ) { return '' ; } const lines = service [ type ] ! . map ( f => `${ f . name }:(parameter:${ f . parametersTypeName }<DeSerializersT>)=>${ f . name }(parameter,this.deSerializers)` ) ; return codeBlock `
  get ${ type }( ) {
    return {${ lines . join ( ',' ) }}
  }
  ` ; } function getBatch ( ) { return codeBlock `
  get batch(): typeof batch {
    return batch;
  }
  ` ; } function getEntityApiFunction ( entity , service ) { return codeBlock `get ${ getApiName ( entity . className ) }(): ${ entity . className }Api<DeSerializersT> { 
    ${ entity . navigationProperties . length ? withLinks ( entity , service ) : withoutLinks ( entity ) }    
  }` ; } function withoutLinks ( entity ) { return `return ${ getApiInitializer ( entity . className ) }` ; } function withLinks ( entity , service ) { return `const api = ${ getApiInitializer ( entity . className ) };
  const linkedApis = [
    ${ entity . navigationProperties . map ( navProp => getApiInitializer ( matchEntity ( navProp , service ) . className ) ) . join ( ',\n' ) }
  ];
  api._addNavigationProperties(linkedApis);
  return api` ; } function getApiInitializer ( entityClassName ) { return `this.initApi('${ getApiName ( entityClassName ) }', ${ entityClassName }Api)` ; } internal param entityName returns export function getApiName ( entityName ) { return `${ voca . decapitalize ( entityName ) }Api` ; }