<commit_before>//
//  BartlebysCommandsFacade.swift
//  bartleby
//
//  Created by <NAME> on 24/01/2016.
//  Copyright © 2016 <NAME>. All rights reserved.
//

import Foundation

struct BartlebysCommandFacade {

    static let args = Swift.CommandLine.arguments

    let executableName = NSString(string: args.first!).pathComponents.last!
    let firstArgumentAfterExecutablePath: String? = (args.count >= 2) ? args[1] : nil

    func actOnArguments() {
        switch firstArgumentAfterExecutablePath {
        case nil:
            print(self._noArgMessage())
            exit(EX_NOINPUT)
        case "-h"?, "-help"?, "h"?, "help"?:
            print(self._noArgMessage())
            exit(EX_USAGE)
        case "testChunkerDigest"?:
            let startTime=CFAbsoluteTimeGetCurrent()
            // Chunk trials
            let chunker=Chunker(fileManager: FileManager.default,cryptoKey:Bartleby.configuration.KEY,cryptoSalt:Bartleby.configuration.SHARED_SALT,mode:.digestOnly)
            // let folder=Bartleby.getSearchPath(FileManager.SearchPathDirectory.desktopDirectory)!
            // let folder="/Users/bpds/Documents/Entrepot/Autoformation/Videos"
            let folder="/Users/bpds/Documents/Entrepot/Autoformation/Videos"
            let destFolder=Bartleby.getSearchPath(FileManager.SearchPathDirectory.desktopDirectory)!
            chunker.breakFolderIntoChunk(filesIn: folder,
                                         chunksFolderPath:destFolder+"ChunkerTestSimulated",
                                         progression: { (progression) in
                                            //print(progression)

            }, success: { (chunks) in
                let duration=CFAbsoluteTimeGetCurrent()-startTime

                var totalSize=0
                var blocksNb=0
                var i=0
                var filesAbsolutePaths=[String]()
                for chunk in chunks{
                    i += 1
                    print("\(i) \(chunk.originalSize) \(totalSize) \( (chunk.nodePath) )")
                    totalSize += chunk.originalSize
                    if !filesAbsolutePaths.contains(chunk.nodePath){
                        filesAbsolutePaths.append(chunk.nodePath)
                    }
                    blocksNb += 1
                }
                print("Chunker .digestOnly on large files Duration \(duration) seconds")
                print("Number of files:\(filesAbsolutePaths.count)")
                print("For \(blocksNb) blocks")
                print("\(totalSize/MB) MB")
                print("\(Int(Double(totalSize/MB)/duration)) MB/s")

                exit(EX_OK)
            }, failure: { (chunks, message) in
                print(message)
                exit(EX_DATAERR)
            })

            break
        case "testChunker"? :
            // Chunk trials
            let chunker=Chunker(fileManager: FileManager.default,cryptoKey:Bartleby.configuration.KEY,cryptoSalt:Bartleby.configuration.SHARED_SALT)
            let startTime=CFAbsoluteTimeGetCurrent()
            if let userDir=Bartleby.getSearchPath(FileManager.SearchPathDirectory.desktopDirectory){
                chunker.breakIntoChunk(fileAt:"\(userDir)/FileChunker/large.mp4", relativePath:"/large.mp4", chunksFolderPath: "\(userDir)/Tests-One-Large-File/.blocks", compress: true, encrypt: true
                    ,progression:{ progression in
                        print(progression)
                }, success: { chunks in

                    let breakToChunkDuration=CFAbsoluteTimeGetCurrent()-startTime
                    let joinStartTime=CFAbsoluteTimeGetCurrent()
                    let absolutePaths=chunks.map({ (chunk) -> String in
                        return chunk.chunksFolderPath+chunk.relativePath
                    })
                    chunker.joinChunksToFile(from: absolutePaths, to: "/Users/bpds/Desktop/Tests-One-Large-File/result.mp4", decompress: true, decrypt: true
                        ,progression:{ progression in
                            print(progression)
                    }
                        , success: { path in
                            print("----------------------------------------------------")
                            print("\(path)")
                            print("Break to Chunks Duration \(breakToChunkDuration)")
                            print("Join Chunks Duration \(CFAbsoluteTimeGetCurrent()-joinStartTime)")
                            exit(EX_OK)
                    }, failure: { (message) in
                        print(message)
                        exit(EX_DATAERR)
                    })
                }, failure:{ message in
                    print(message)
                    exit(EX_DATAERR)
                })
            }else{
                exit(EX_OK)
            }

            break
        case "testChunkerFolder"? :

            print("Processing...")
            var chunker=Chunker(fileManager: FileManager.default,cryptoKey:Bartleby.configuration.KEY,cryptoSalt:Bartleby.configuration.SHARED_SALT)
            chunker.destroyChunksFolder=true// Destruct the chunks

            if let userDir=Bartleby.getSearchPath(FileManager.SearchPathDirectory.desktopDirectory){
                let sourceFolder="\(userDir)/FolderForTests"
                let destinationFolder="\(userDir)/TestsFolder"
                chunker.breakFolderIntoChunk(filesIn:sourceFolder,
                                             chunksFolderPath: destinationFolder+"/.blocks",
                                             progression: { (progression) in
                }, success: { (chunks) in

                    // Joins the chunks
                    chunker.joinsChunks(chunks: chunks,
                                        assemblyFolderPath: destinationFolder,
                                        progression: { (progression) in
                                            print (progression)
                    }, success: {
                        print ("Success")
                        exit(EX_OK)
                    }, failure: { (paths, error) in
                        print ("Failure \(error)")
                        exit(EX_DATAERR)
                    })
                }, failure: { (chunks, message) in
                    print(message)
                    exit(EX_DATAERR)
                })
            }else{
                exit(EX_OK)
            }
            break
        case "testFlocker"? :

            var flockStats:BytesStats?

            func __unFlock(using flocker:Flocker){
                if let userDir=Bartleby.getSearchPath(FileManager.SearchPathDirectory.desktopDirectory){
                    let source="\(userDir)/flock.flk"
                    let destination="\(userDir)/Unflocked"
                    flocker.unFlock(flockedFile: source, to: destination, progression: { (progression) in
                        print(progression.message)
                    }, success: { unFlockStats in
                        print("\n-----")
                        print(flockStats!)
                        print(unFlockStats)
                        exit(EX_OK)
                    }, failure: { (message) in
                        print("\(message)")
                    })
                }else{
                    exit(EX_OK)
                }
            }

            func __flock(){
                let flocker=Flocker(fileManager: FileManager.default,cryptoKey:Bartleby.configuration.KEY,cryptoSalt:Bartleby.configuration.SHARED_SALT)
                if let userDir=Bartleby.getSearchPath(FileManager.SearchPathDirectory.desktopDirectory){
                    let sourceFolder="\(userDir)/FolderForTests"
                    let destination="\(userDir)/flock.flk"
                    var sourceRef=FileReference.publicFileReference(at: sourceFolder)
                    sourceRef.crypted=true
                    sourceRef.compressed=true
                    sourceRef.priority=1
                    flocker.flockFolder(folderReference: sourceRef, destination: destination, progression: { (progression) in
                        print(progression.message)
                    }, success: { stats in
                        flockStats=stats
                        __unFlock(using:flocker)
                    }, failure: { (container, message) in
                        print(message)
                        exit(EX_DATAERR)
                    })
                }else{
                    exit(EX_OK)
                }
            }
            __flock()

            break
        default:
            // We want to propose the best verb candidate
            let reference=[
                "h", "help",
                "install",
                "create",
                "generate",
                "update",
                "testChunker",
                "testChunkerDigest",
                "testChunkerFolder",
                "testFlocker"
            ]
            let bestCandidate=self.bestCandidate(string: firstArgumentAfterExecutablePath!, reference: reference)
            print("Hey ...\"bartleby \(firstArgumentAfterExecutablePath!)\" is unexpected!")
            print("Did you mean:\"bartleby \(bestCandidate)\"?")
        }
    }



    private func _noArgMessage() -> String {
        var s=""
        s += "Bartleby's CLI"
        s += "\nCreated by <NAME>"
        s += "\nhttps://pereira-da-silva.com for Chaosmos SAS"
        s += "\n"<commit_msg>Test facade update<commit_after>//
//  BartlebysCommandsFacade.swift
//  bartleby
//
//  Created by <NAME> on 24/01/2016.
//  Copyright © 2016 Benoit <NAME>. All rights reserved.
//

import Foundation

struct BartlebysCommandFacade {

    static let args = Swift.CommandLine.arguments

    let executableName = NSString(string: args.first!).pathComponents.last!
    let firstArgumentAfterExecutablePath: String? = (args.count >= 2) ? args[1] : nil

    func actOnArguments() {
        switch firstArgumentAfterExecutablePath {
        case nil:
            print(self._noArgMessage())
            exit(EX_NOINPUT)
        case "-h"?, "-help"?, "h"?, "help"?:
            print(self._noArgMessage())
            exit(EX_USAGE)
        case "testChunkerDigest"?:
            let startTime=CFAbsoluteTimeGetCurrent()
            // Chunk trials
            let chunker=Chunker(fileManager: FileManager.default,cryptoKey:Bartleby.configuration.KEY,cryptoSalt:Bartleby.configuration.SHARED_SALT,mode:.digestOnly)
            // let folder=Bartleby.getSearchPath(FileManager.SearchPathDirectory.desktopDirectory)!
            // let folder="/Users/bpds/Documents/Entrepot/Autoformation/Videos"
            let folder="/Users/bpds/Documents/Entrepot/Autoformation/Videos"
            let destFolder=Bartleby.getSearchPath(FileManager.SearchPathDirectory.desktopDirectory)!
            chunker.breakFolderIntoChunk(filesIn: folder,
                                         chunksFolderPath:destFolder+"ChunkerTestSimulated",
                                         progression: { (progression) in
                                            //print(progression)

            }, success: { (chunks) in
                let duration=CFAbsoluteTimeGetCurrent()-startTime

                var totalSize=0
                var blocksNb=0
                var i=0
                var filesAbsolutePaths=[String]()
                for chunk in chunks{
                    i += 1
                    print("\(i) \(chunk.originalSize) \(totalSize) \( (chunk.nodePath) )")
                    totalSize += chunk.originalSize
                    if !filesAbsolutePaths.contains(chunk.nodePath){
                        filesAbsolutePaths.append(chunk.nodePath)
                    }
                    blocksNb += 1
                }
                print("Chunker .digestOnly on large files Duration \(duration) seconds")
                print("Number of files:\(filesAbsolutePaths.count)")
                print("For \(blocksNb) blocks")
                print("\(totalSize/MB) MB")
                print("\(Int(Double(totalSize/MB)/duration)) MB/s")

                exit(EX_OK)
            }, failure: { (chunks, message) in
                print(message)
                exit(EX_DATAERR)
            })

            break
        case "testChunker"? :
            // Chunk trials
            let chunker=Chunker(fileManager: FileManager.default,cryptoKey:Bartleby.configuration.KEY,cryptoSalt:Bartleby.configuration.SHARED_SALT)
            let startTime=CFAbsoluteTimeGetCurrent()
            if let userDir=Bartleby.getSearchPath(FileManager.SearchPathDirectory.desktopDirectory){
                chunker.breakIntoChunk(fileAt:"\(userDir)/FileChunker/large.mp4", relativePath:"/large.mp4", chunksFolderPath: "\(userDir)/Tests-One-Large-File/.blocks", compress: true, encrypt: true
                    ,progression:{ progression in
                        print(progression)
                }, success: { chunks in

                    let breakToChunkDuration=CFAbsoluteTimeGetCurrent()-startTime
                    let joinStartTime=CFAbsoluteTimeGetCurrent()
                    let absolutePaths=chunks.map({ (chunk) -> String in
                        return chunk.chunksFolderPath+chunk.relativePath
                    })
                    chunker.joinChunksToFile(from: absolutePaths, to: "/Users/bpds/Desktop/Tests-One-Large-File/result.mp4", decompress: true, decrypt: true
                        ,progression:{ progression in
                            print(progression)
                    }
                        , success: { path in
                            print("----------------------------------------------------")
                            print("\(path)")
                            print("Break to Chunks Duration \(breakToChunkDuration)")
                            print("Join Chunks Duration \(CFAbsoluteTimeGetCurrent()-joinStartTime)")
                            exit(EX_OK)
                    }, failure: { (message) in
                        print(message)
                        exit(EX_DATAERR)
                    })
                }, failure:{ message in
                    print(message)
                    exit(EX_DATAERR)
                })
            }else{
                exit(EX_OK)
            }

            break
        case "testChunkerFolder"? :

            print("Processing...")
            var chunker=Chunker(fileManager: FileManager.default,cryptoKey:Bartleby.configuration.KEY,cryptoSalt:Bartleby.configuration.SHARED_SALT)
            chunker.destroyChunksFolder=true// Destruct the chunks

            if let userDir=Bartleby.getSearchPath(FileManager.SearchPathDirectory.desktopDirectory){
                let sourceFolder="\(userDir)/FolderForTests"
                let destinationFolder="\(userDir)/TestsFolder"
                chunker.breakFolderIntoChunk(filesIn:sourceFolder,
                                             chunksFolderPath: destinationFolder+"/.blocks",
                                             progression: { (progression) in
                }, success: { (chunks) in

                    // Joins the chunks
                    chunker.joinsChunks(chunks: chunks,
                                        assemblyFolderPath: destinationFolder,
                                        progression: { (progression) in
                                            print (progression)
                    }, success: {
                        print ("Success")
                        exit(EX_OK)
                    }, failure: { (paths, error) in
                        print ("Failure \(error)")
                        exit(EX_DATAERR)
                    })
                }, failure: { (chunks, message) in
                    print(message)
                    exit(EX_DATAERR)
                })
            }else{
                exit(EX_OK)
            }
            break


        case "testFlocker"? :

            var flockStats:BytesStats?

            func __unFlock(using flocker:Flocker){
                if let userDir=Bartleby.getSearchPath(FileManager.SearchPathDirectory.desktopDirectory){
                    let source="\(userDir)/flock.flk"
                    let destination="\(userDir)/Unflocked"
                    flocker.unFlock(flockedFile: source, to: destination, progression: { (progression) in
                        print(progression.message)
                    }, success: { unFlockStats in
                        print("\n-----")
                        if let f=flockStats{
                            print(f)
                        }
                        print(unFlockStats)
                        exit(EX_OK)
                    }, failure: { (message) in
                        print("\(message)")
                    })
                }else{
                    exit(EX_OK)
                }
            }

            func __flock(){
                let flocker=Flocker(fileManager: FileManager.default,cryptoKey:Bartleby.configuration.KEY,cryptoSalt:Bartleby.configuration.SHARED_SALT)
                if let userDir=Bartleby.getSearchPath(FileManager.SearchPathDirectory.desktopDirectory){
                    let sourceFolder="\(userDir)/FolderForTests"
                    let destination="\(userDir)/flock.flk"
                    var sourceRef=FileReference.publicFileReference(at: sourceFolder)
                    sourceRef.crypted=true
                    sourceRef.compressed=true
                    sourceRef.priority=1
                    sourceRef.chunkMaxSize=10*MB
                    flocker.flockFolder(folderReference: sourceRef, destination: destination, progression: { (progression) in
                        print(progression.message)
                    }, success: { stats in
                        flockStats=stats
                        __unFlock(using:flocker)
                    }, failure: { (container, message) in
                        print(message)
                        exit(EX_DATAERR)
                    })
                }else{
                    exit(EX_OK)
                }
            }
            //__flock()
            let flocker=Flocker(fileManager: FileManager.default,cryptoKey:Bartleby.configuration.KEY,cryptoSalt:Bartleby.configuration.SHARED_SALT)
            __unFlock(using: flocker)

            break
        default:
            // We want to propose the best verb candidate
            let reference=[
                "h", "help",
                "install",
                "create",
                "generate",
                "update",
                "testChunker",
                "testChunkerDigest",
                "testChunkerFolder",
                "testFlocker"
            ]
            let bestCandidate=self.bestCandidate(string: firstArgumentAfterExecutablePath!, reference: reference)
            print("Hey ...\"bartleby \(firstArgumentAfterExecutablePath!)\" is unexpected!")
            print("Did you mean:\"bartleby \(bestCandidate)\"?")
        }
    }



    private func _noArgMessage() -> String {
        var s=""
        s += "Bartleby's CLI"
        s += "\nCreated by <NAME>"
        s += "\nhttps://pereira-da-silva.com for Chaosmos SAS"
        s += "\n"
{'fraction_non_alphanumeric': 0.0981795550023339, 'fraction_numerical': 0.0024894974327057725, 'mean_word_length': 1.3816699604743083, 'pattern_counts': {'":': 0, '<': 9, '<?xml version=': 0, '>': 15, 'https://': 2, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 28, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5038298', 'n_tokens_mistral': 4896, 'n_tokens_neox': 4495, 'n_words': 805}