'use strict' ; import request = require ( 'request' ) ; import { sleep } from '../utils' ; import { HappeningType , HelpfulAction , search } from 'pddl-workspace' ; import { DEFAULT_EPSILON } from '../configuration/configuration' ; export class MockSearch { url : string ; constructor ( port ) { this . url = `http://localhost:${ port }` ; } async run ( ) { const helloWorld = await new Promise < string > ( ( resolve , reject ) => { request . get ( this . url + '/about' , ( error , httpResponse , httpBody ) => { if ( error ) { reject ( error ) ; return ; } else { if ( httpResponse && httpResponse . statusCode > 204 ) { reject ( "HTTP status code " + httpResponse . statusCode ) ; return ; } else { resolve ( httpBody ) ; } } } ) ; } ) ; console . log ( helloWorld ) ; for ( const mockEvent of this . events ) { console . log ( "sending mock event: " ) ; console . log ( mockEvent ) ; await sleep ( 100 ) ; try { await this . send ( mockEvent ) ; } catch ( ex ) { console . log ( ex ) ; break ; } } console . log ( 'Mock-search finished.' ) ; } private async send ( mockEvent ) { switch ( mockEvent . operation ) { case 'post-initial' : return await this . post ( '/state/initial' , mockEvent . toWireMessage ( ) ) ; case 'post' : return await this . post ( '/state' , mockEvent . toWireMessage ( ) ) ; case 'patch' : return await this . post ( '/state/heuristic' , mockEvent . toWireMessage ( ) ) ; default : console . log ( "Unsupported mock event: " + mockEvent . operation ) ; } } private async post ( path , content ) { return await new Promise < void > ( ( resolve , reject ) => { request . post ( this . url + path , { json : content } , ( error , httpResponse ) => { if ( error ) { reject ( error ) ; return ; } else { if ( httpResponse && httpResponse . statusCode > 204 ) { reject ( 'HTTP status code ' + httpResponse . statusCode ) ; return ; } else { resolve ( void 0 ) ; } } } ) ; } ) ; } /**
     * the `patch` method will be useful when the contract migrates `patch` HTTP verb.
     */ private state0 : MockStateContext | undefined = undefined ; private state0_0 : MockStateContext | undefined = undefined ; private state0_1 : MockStateContext | undefined = undefined ; private state0_0_0 : MockStateContext | undefined = undefined ; private state0_0_1 : MockStateContext | undefined = undefined ; private state0_1_0 : MockStateContext | undefined = undefined ; private state0_1_1 : MockStateContext | undefined = undefined ; private state0_1_0_0 : MockStateContext | undefined = undefined ; private state0_1_0_0_0 : MockStateContext | undefined = undefined ; private readonly events = [ new MockStateContextEvent ( "post-initial" , this . state0 = MockStateContext . createInitial ( ) ) , new MockStateSearchContextEvent ( "patch" , this . state0 . evaluate ( 5 , [ MockHelpfulAction . start ( "drive" ) , MockHelpfulAction . start ( "load" ) ] , state => state . buildRelaxedPlan ( ) . start ( "drive" ) . start ( "load" ) . end ( 1 , "load" ) . end ( 3 , "drive" ) ) ) , new MockStateContextEvent ( "post" , this . state0_0 = this . state0 . applyStart ( "drive" , 0 ) ) , new MockStateContextEvent ( "post" , this . state0_1 = this . state0 . applyStart ( "load" , 0 ) ) , new MockStateSearchContextEvent ( "patch" , this . state0_0 . evaluate ( 5 , [ MockHelpfulAction . start ( "load" ) , MockHelpfulAction . end ( "drive" ) ] , state => state . buildRelaxedPlan ( ) . end ( 4 , "drive" ) . start ( "load" ) . end ( 1 , "load" ) ) ) , new MockStateSearchContextEvent ( "patch" , this . state0_1 . evaluate ( 4 , [ MockHelpfulAction . start ( "drive" ) , MockHelpfulAction . end ( "load" ) ] , state => state . buildRelaxedPlan ( ) . end ( 1 , "load" ) . start ( "drive" ) . end ( 4 , "drive" ) ) ) , new MockStateContextEvent ( "post" , this . state0_0_0 = this . state0_0 . applyEnd ( "drive" , 0 , 3 ) ) , new MockStateContextEvent ( "post" , this . state0_0_1 = this . state0_0 . applyStart ( "load" , 0 ) ) , new MockStateSearchContextEvent ( "patch" , this . state0_0_0 . evaluate ( 4 , [ MockHelpfulAction . start ( "load" ) ] , state => state . buildRelaxedPlan ( ) . start ( "load" ) . end ( 1 , "load" ) ) ) , new MockStateSearchContextEvent ( "patch" , this . state0_0_1 . evaluate ( 3 , [ MockHelpfulAction . end ( "load" ) , MockHelpfulAction . end ( "drive" ) ] , state => state . buildRelaxedPlan ( ) . end ( 4 , "drive" ) . end ( 1 , "load" ) ) ) , new MockStateContextEvent ( "post" , this . state0_1_0 = this . state0_1 . applyEnd ( "load" , 0 , .5 ) ) , new MockStateContextEvent ( "post" , this . state0_1_1 = this . state0_1 . applyStart ( "drive" , 0 ) ) , new MockStateSearchContextEvent ( "patch" , this . state0_1_0 . evaluate ( 2 , [ MockHelpfulAction . start ( "drive" ) ] , state => state . buildRelaxedPlan ( ) . start ( "drive" ) . end ( 4 , "drive" ) ) ) , new MockStateSearchContextEvent ( "patch" , this . state0_1_1 . evaluate ( 3 , [ MockHelpfulAction . end ( "drive" ) , MockHelpfulAction . end ( "load" ) ] , state => state . buildRelaxedPlan ( ) . end ( 4 , "drive" ) . end ( 1 , "load" ) ) ) , new MockStateContextEvent ( "post" , this . state0_1_0_0 = this . state0_1_0 . applyStart ( "drive" , 0 ) ) , new MockStateSearchContextEvent ( "patch" , this . state0_1_0_0 . evaluate ( 1 , [ MockHelpfulAction . end ( "drive" ) ] , state => state . buildRelaxedPlan ( ) . end ( 4 , "drive" ) ) ) , new MockStateContextEvent ( "post" , this . state0_1_0_0_0 = this . state0_1_0_0 . applyEnd ( "drive" , 0 , 4 ) ) , new MockStateSearchContextEvent ( "patch" , this . state0_1_0_0_0 . evaluate ( 0 , [ ] , state => state . buildRelaxedPlan ( ) ) ) , ] ; } abstract class MockEvent { constructor ( public readonly operation ) { } abstract toWireMessage ( ) ; } class MockStateContextEvent extends MockEvent { constructor ( readonly operation , public readonly stateContext ) { super ( operation ) ; } toWireMessage ( ) { return { id : this . stateContext . state . id , parentId : this . stateContext . parentId , g : this . stateContext . g , earliestTime : this . stateContext . earliestTime , appliedAction : this . stateContext . appliedAction ? toWireSearchHappening ( this . stateContext . appliedAction ) : null , planHead : this . stateContext . planHead . map ( h => toWireSearchHappening ( h ) ) } ; } } class MockStateSearchContextEvent extends MockEvent { constructor ( readonly operation , public readonly stateSearchContext ) { super ( operation ) ; } toWireMessage ( ) { return { id : this . stateSearchContext . stateContext . state . id , totalMakespan : this . stateSearchContext . totalMakespan , h : this . stateSearchContext . h , helpfulActions : this . stateSearchContext . helpfulActions . map ( a => toWireHelpfulAction ( a ) ) , relaxedPlan : this . stateSearchContext . relaxedPlan . map ( h => toWireSearchHappening ( h ) ) } ; } } function toWireSearchHappening ( happening ) { return { earliestTime : happening . earliestTime , actionName : happening . actionName , shotCounter : happening . shotCounter , kind : HappeningType [ happening . kind ] } ; } function toWireHelpfulAction ( action ) { return { actionName : action . actionName , kind : HappeningType [ action . kind ] } ; } class MockStateSearchContext { constructor ( public readonly stateContext , public readonly totalMakespan , public readonly h , public readonly helpfulActions , public readonly relaxedPlan ) { } } class MockStateContext { static createInitial ( ) { return new MockStateContext ( MockState . createInitial ( ) , 0 , EPSILON , undefined , [ ] , undefined ) ; } constructor ( public readonly state , public readonly g , public readonly earliestTime , public readonly appliedAction , public readonly planHead , public readonly parentId ? ) { } get actionName ( ) : string | undefined { return this . appliedAction ?. actionName ; } isInitialState ( ) { return this . planHead . length === 0 ; } getLastHappening ( ) { if ( this . isInitialState ( ) ) { throw new Error ( "Check if this is an initial state first.." ) ; } return this . planHead [ this . planHead . length - 1 ] ; } applyStart ( actionName , shotCounter ) { return this . apply ( actionName , shotCounter , HappeningType . START , EPSILON ) ; } applyEnd ( actionName , shotCounter , duration ) { return this . apply ( actionName , shotCounter , HappeningType . END , duration ) ; } apply ( actionName , shotCounter , kind , timeIncrement ) { const id = ++ MockState . lastStateId ; const earliestTime = this . earliestTime + timeIncrement ; const appliedAction = new MockSearchHappening ( earliestTime , actionName , shotCounter , 1 , kind , false ) ; const newPlanHead = this . planHead . concat ( [ appliedAction ] ) ; return new MockStateContext ( new MockState ( id . toString ( ) ) , this . g + 1 , earliestTime , appliedAction , newPlanHead , this . state . id ) ; } evaluate ( h , helpfulActions , relaxedPlanFactory ) { const relaxedStateBuilder = relaxedPlanFactory ( this ) ; const relaxedPlan = relaxedStateBuilder . build ( ) ; const totalMakespan = relaxedPlan . length ? Math . max ( ... relaxedPlan . map ( step => step . earliestTime ) ) : this . earliestTime ; const newState = new MockStateSearchContext ( this , totalMakespan , h , helpfulActions , relaxedPlan ) ; return newState ; } buildRelaxedPlan ( ) { return new RelaxedPlanBuilder ( this . earliestTime ) ; } toString ( ) { return `State={id: ${ this . state . id }, G: ${ this . g }}` ; } } class MockState { constructor ( public readonly id ) { } static createInitial ( ) { const id = ++ this . lastStateId ; return new MockState ( id . toString ( ) ) ; } static lastStateId = - 1 ; } const EPSILON = DEFAULT_EPSILON ; class RelaxedPlanBuilder { happenings : search . SearchHappening [ ] = [ ] ; time : number ; constructor ( private readonly earliestStateTime ) { this . time = this . earliestStateTime ; } start ( actionName ) { const time = this . time += EPSILON ; this . happenings . push ( new MockSearchHappening ( time , actionName , 0 , 1 , HappeningType . START , true ) ) ; return this ; } end ( timeOffset , actionName ) { const time = this . time += timeOffset ; this . happenings . push ( new MockSearchHappening ( time , actionName , 0 , 1 , HappeningType . END , true ) ) ; return this ; } build ( ) { return this . happenings ; } } class MockSearchHappening implements search . SearchHappening { constructor ( public readonly earliestTime , public readonly actionName , public readonly shotCounter , public readonly iterations , public readonly kind , public readonly isRelaxed ) { } toString ( ) { const relaxed = this . isRelaxed ? '*' : '' ; const iterations = this . iterations > 1 ? ` ${ this . iterations }x` : '' ; return `${ this . earliestTime }: ${ this . actionName }[${ this . shotCounter }] ${ this . kind }${ relaxed }${ iterations }` ; } } class MockHelpfulAction implements HelpfulAction { constructor ( public readonly actionName , public readonly kind ) { } static start ( actionName ) { return new MockHelpfulAction ( actionName , HappeningType . START ) ; } static end ( actionName ) { return new MockHelpfulAction ( actionName , HappeningType . END ) ; } }