/**
 * Copyright (c) 2016-present, Facebook, Inc.
 *
 * This source code is licensed under the MIT license found in the
 * LICENSE file in the root directory of this source tree.
 */ import * as colors from 'cli-color' ; import * as CommandLine from './commandline' ; import * as Either from './either' ; import * as Error from './error' ; import * as FileWriter from './file-writer' ; import * as List from './list' ; import * as Logging from './logging' ; import * as LoggingSequenceUtils from './logged-sequence-utils' ; import * as LazySequence from './lazy-sequence' ; import * as Maybe from './maybe' ; import * as Promise from './promise' ; export interface ObjectGenerationSuccess { name : string ; } export interface ConsoleOutputResults { errorCount : number ; successCount : number ; } function trackConsoleOutput ( soFar , thisOutput ) { return Promise . mbind ( function ( lcResults ) { return Promise . map ( function ( output ) { return Logging . mbind ( function ( results ) { return Logging . map ( function ( either ) { return Either . match ( function ( errors ) : ConsoleOutputResults { return { errorCount : results . errorCount + 1 , successCount : results . successCount } ; } , function ( success ) : ConsoleOutputResults { return { errorCount : results . errorCount , successCount : results . successCount + 1 } ; } , either ) ; } , output ) ; } , lcResults ) ; } , thisOutput ) ; } , soFar ) ; } function loggerForParsedArgs ( parsedArgs ) { return { interestedLoggingTypes : parsedArgs . interestedLoggingTypes , minimalLevel : parsedArgs . minimalLevel , processLog : function ( loggingType , time , info ) { const infoStr = displayInfo ( loggingType , time , info ) ; console . log ( infoStr ) ; } } ; } function performanceDisplayInfo ( time , info ) { return colors . yellow ( '[perf][' + time + '] ' + info ) ; } function errorDisplayInfo ( time , info ) { return colors . red ( '[error][' + time + '] ' + info ) ; } function displayInfo ( loggingType , time , info ) { switch ( loggingType ) { case Logging . LoggingType . performance : return performanceDisplayInfo ( time , info ) ; case Logging . LoggingType . error : return errorDisplayInfo ( time , info ) ; default : return info ; } } function propagateGenerationSuccessError ( errors ) { return Promise . munit ( Logging . munit ( Either . Left < Error . Error [ ] , ObjectGenerationSuccess > ( errors ) ) ) ; } function failOnError ( soFar , thisOne ) { return Either . mbind ( function ( success ) { return Maybe . match ( function ( errors ) { return Either . Left < Error . Error [ ] , ObjectGenerationSuccess > ( [ errors ] ) ; } , function ( ) { return soFar ; } , thisOne ) ; } , soFar ) ; } function generateOutput ( either ) { return Promise . munit ( Either . match ( function ( errors ) { const message = errors . map ( Error . getReason ) . join ( '\n' ) ; return Logging . Error ( 10 , message , either ) ; } , function ( success ) { return Logging . Info ( 10 , success . name + ' Generated' , either ) ; } , either ) ) ; } function writeRequestToEitherErrorOrGenerationSuccess ( fileWriter , request ) { const promiseForAllWriteRequestsFinished = Promise . all ( List . map ( fileWriter , request . requests ) ) ; return Promise . map ( function ( results ) { const success = Either . Right < Error . Error [ ] , ObjectGenerationSuccess > ( { name : request . name } ) ; return Logging . munit ( List . foldl ( failOnError , success , results ) ) ; } , promiseForAllWriteRequestsFinished ) ; } function writeFiles ( fileWriter , either ) { return Either . match ( propagateGenerationSuccessError , ( request ) => writeRequestToEitherErrorOrGenerationSuccess ( fileWriter , request ) , either ) ; } function writeFileForDryRun ( request ) { const promise = Promise . pending < Error . Error | null > ( ) ; promise . setValue ( null ) ; return promise . getFuture ( ) ; } function writeAndLogSequence ( parsedArgs , evaluatedSequence ) { const outputResults = LazySequence . foldl ( trackConsoleOutput , Promise . resolved ( Logging . munit < ConsoleOutputResults > ( { errorCount : 0 , successCount : 0 } ) ) . getFuture ( ) , evaluatedSequence ) ; const resultingLoggingContext = Promise . mbind ( function ( future ) { return Promise . map ( function ( lcResults ) { return lcResults . value ; } , future ) ; } , outputResults ) ; return resultingLoggingContext ; } export function evaluateObjectFileWriteRequestSequence ( parsedArgs , writeRequestSequence ) { const fileWriter = parsedArgs . dryRun ? writeFileForDryRun : FileWriter . write ; const writtenFileSequence = LoggingSequenceUtils . mapLoggedSequence3 ( writeRequestSequence , ( request ) => writeFiles ( fileWriter , request ) , generateOutput ) ; const evaluatedSequence = LoggingSequenceUtils . evaluatedLoggedSequence ( loggerForParsedArgs ( parsedArgs ) , writtenFileSequence ) ; return writeAndLogSequence ( parsedArgs , evaluatedSequence ) ; }