
//
//  TreeTraversalProtocol.swift
//  MVMCoreUI
//
//  Created by Kyle on 3/19/21.
//  Copyright © 2021 Verizon Wireless. All rights reserved.
//

public enum TreeTraversalOptions {
    case parentFirst
    case childFirst
    case leafNodesOnly
}

public protocol MoleculeTreeTraversalProtocol {
        
    // Future options -- Parent first depth first, leaves only.
    
    func reduceDepthFirstTraverse<Result>(options: TreeTraversalOptions, depth: Int, initialResult: Result, nextPartialResult: (Result, MoleculeModelProtocol, Int)->Result) -> Result
    
    func depthFirstTraverse(options: TreeTraversalOptions, depth: Int, onVisit: (Int, MoleculeModelProtocol)->Void)
    
    //func breadthFirstTraverse()
}

//
// Helper Extensions
//

public extension MoleculeTreeTraversalProtocol {
    
    func countMolecules(options: TreeTraversalOptions = .parentFirst) -> Int {
        return reduceDepthFirstTraverse(options: options, depth: 0, initialResult: 0) { (accumulator, molecule, depth) in
            return accumulator + 1
        }
    }
    
    func printMolecules(options: TreeTraversalOptions = .parentFirst) {
        depthFirstTraverse(options: options, depth: 1) { (depth, molecule) in
            print("\(String(repeating: ">>", count: depth)) \"\(molecule.moleculeName)\" [\(molecule)]")
        }
    }
    
    func allMoleculesOfType<T>(options: TreeTraversalOptions = .parentFirst) -> [T] {
        return reduceDepthFirstTraverse(options: options, depth: 0, initialResult: []) { (accumulator, molecule, depth) in
            if let typedMolecule = molecule as? T {
                return accumulator + [typedMolecule]
            }
            return accumulator
        }
    }
}
