// Copyright 2016 The Tulsi Authors. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//      http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

import Cocoa


// Models a node in the source filter picker.
final class SourcePathNode: UISelectableOutlineViewNode {

  /// Whether or not this specific node is set as recursive-enabled (rather than some child marking
  /// it as mixed state).
  @objc dynamic var explicitlyRecursive: Bool {
    return recursive == NSControl.StateValue.on.rawValue
  }

  /// This node's recursive UI state (NSOnState/NSOffState/NSMixedState).
  @objc dynamic var recursive: Int {
    get {
      guard let entry = entry as? UISourcePath else { return NSControl.StateValue.off.rawValue }
      if entry.recursive { return NSControl.StateValue.on.rawValue }

      for child in children as! [SourcePathNode] {
        if child.recursive != NSControl.StateValue.off.rawValue {
          return NSControl.StateValue.mixed.rawValue
        }
      }
      return NSControl.StateValue.off.rawValue
    }

    set {
      // No work needs to be done for mixed state, as it does not affect the underlying values.
      if newValue == NSControl.StateValue.mixed.rawValue { return }

      guard let entry = entry as? UISourcePath else { return }
      let enabled = newValue == NSControl.StateValue.on.rawValue
      willChangeValue(forKey: "explicitlyRecursive")
      entry.recursive = enabled
      didChangeValue(forKey: "explicitlyRecursive")

      // If this node is newly recursive, force hasRecursiveEnabledParent, otherwise have children
      // inherit this node's status.
      setChildrenHaveRecursiveParent(enabled || hasRecursiveEnabledParent)

      // Notify KVO that this node's ancestors have also changed state.
      var ancestor = parent
      while ancestor != nil {
        ancestor!.willChangeValue(forKey: "recursive")
        ancestor!.didChangeValue(forKey: "recursive")
        ancestor = ancestor!.parent
      }
    }
  }

  @objc dynamic var hasRecursiveEnabledParent: Bool = false {
    willSet {
      // If this node is recursive its children will still have a recursive parent and there's no
      // need to update them.
      if recursive == NSControl.StateValue.on.rawValue || newValue == hasRecursiveEnabledParent { return }
      setChildrenHaveRecursiveParent(newValue)
    }
  }

  // TODO(abaire): Use a custom control to override nextState: such that it's never set to mixed via user interaction.
  @objc func validateRecursive(_ ioValue: AutoreleasingUnsafeMutablePointer<AnyObject?>) throws {
    if let value = ioValue.pointee as? NSNumber {
      if value.intValue == NSControl.StateValue.mixed.rawValue {
        ioValue.pointee = NSNumber(value: NSControl.StateValue.on.rawValue as Int)
      }
    }
  }

  // MARK: - Private methods

  fileprivate func setChildrenHaveRecursiveParent(_ newValue: Bool) {
    for child in children as! [SourcePathNode] {
      child.hasRecursiveEnabledParent = newValue
      // Children of a recursive-enabled node may not be recursive themselves (it's redundant and
      // potentially confusing).
      if newValue {
        child.recursive = NSControl.StateValue.off.rawValue
      }
    }
  }
}


// Controller for the view allowing users to select a subset of the source files to include in the
// generated Xcode project.
final class ConfigEditorSourceFilterViewController: NSViewController, WizardSubviewProtocol {
  @objc dynamic var sourceFilterContentArray: [SourcePathNode] = []
  @IBOutlet weak var sourceFilterOutlineView: NSOutlineView!

  override func viewDidLoad() {
    super.viewDidLoad()
    let sourceTargetColumn = sourceFilterOutlineView.tableColumn(withIdentifier: NSUserInterfaceItemIdentifier(rawValue: "sourceTargets"))!
    sourceFilterOutlineView.sortDescriptors = [sourceTargetColumn.sortDescriptorPrototype!]
  }

  // MARK: - WizardSubviewProtocol

  weak var presentingWizardViewController: ConfigEditorWizardViewController? = nil

  func wizardSubviewWillActivateMovingForward() {
    let document = representedObject as! TulsiGeneratorConfigDocument
    sourceFilterContentArray = []
    document.updateSourcePaths(populateOutlineView)

    // TODO(abaire): Set when toggling selection instead.
    document.updateChangeCount(.changeDone)  // TODO(abaire): Implement undo functionality.
  }

  // MARK: - Private methods

  private func populateOutlineView(_ sourcePaths: [UISourcePath]) {
    // Decompose each rule and merge into a tree of subelements.
    let componentDelimiters = CharacterSet(charactersIn: "/:")
    let splitSourcePaths = sourcePaths.map() {
      $0.path.components(separatedBy: componentDelimiters)
    }

    var recursiveNodes = [SourcePathNode]()

    let topNode = SourcePathNode(name: "")
    for i in 0 ..< splitSourcePaths.count {
      let label = splitSourcePaths[i]
      var node = topNode
      elementLoop: for element in label {
        if element == "" {
          continue
        }
        for child in node.children as! [SourcePathNode] {
          if child.name == element {
            node = child
            continue elementLoop
          }
        }
        let newNode = SourcePathNode(name: element)
        node.addChild(newNode)
        node = newNode
      }
      node.entry = sourcePaths[i]
      if node.recursive == NSControl.StateValue.on.rawValue {
        recursiveNodes.append(node)
      }
    }

    // Patch up the recursive status now that the entire tree is constructed.
    for node in recursiveNodes {
      node.setChildrenHaveRecursiveParent(true)
    }

    sourceFilterContentArray = topNode.children as! [SourcePathNode]
  }
}
