// 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
import TulsiGenerator


/// View controller for the editor that allows management of Generator Configs associated with a
/// project.
final class ProjectEditorConfigManagerViewController: NSViewController {

  /// Indices into the Add/Remove/Action SegmentedControl (as built by Interface Builder).
  private enum SegmentedControlButtonIndex: Int {
    case add = 0
    case remove = 1
    case action = 2
  }

  // Context indicating that a new config should be added after a document save completes.
  private static var PostSaveContextAddConfig = 0

  @IBOutlet var configArrayController: NSArrayController!
  @IBOutlet weak var addRemoveSegmentedControl: NSSegmentedControl!
  @IBOutlet var generateButton: NSButton!

  @objc dynamic var numBazelPackages: Int = 0 {
    didSet {
      let enableAddButton = numBazelPackages > 0 && infoExtractorInitialized
      addRemoveSegmentedControl.setEnabled(enableAddButton,
                                           forSegment: SegmentedControlButtonIndex.add.rawValue)
    }
  }

  // Whether or not the Tulsi project document is still initializing components required for
  // generation.
  @objc dynamic var infoExtractorInitialized: Bool = false {
    didSet {
      updateButtonsState()
      Thread.doOnMainQueue() {
        self.generateButton.title = self.infoExtractorInitialized ? "Generate" : "Initializing..."
      }
    }
  }

  @objc dynamic var numSelectedConfigs: Int = 0 {
    didSet {
      updateButtonsState()
    }
  }

  override var representedObject: Any? {
    didSet {
      if let concreteRepresentedObject = representedObject {
        bind(NSBindingName(rawValue: "numBazelPackages"),
             to: concreteRepresentedObject,
             withKeyPath: "bazelPackages.@count",
             options: nil)
        bind(NSBindingName(rawValue: "infoExtractorInitialized"),
             to: concreteRepresentedObject,
             withKeyPath: "infoExtractorInitialized",
             options: nil)
      }
    }
  }

  deinit {
    NSObject.unbind(NSBindingName(rawValue: "infoExtractorInitialized"))
    NSObject.unbind(NSBindingName(rawValue: "numBazelPackages"))
    NSObject.unbind(NSBindingName(rawValue: "numSelectedConfigs"))
  }

  override func loadView() {
    ValueTransformer.setValueTransformer(IsOneValueTransformer(),
                                           forName: NSValueTransformerName(rawValue: "IsOneValueTransformer"))
    super.loadView()
    bind(NSBindingName(rawValue: "numSelectedConfigs"),
         to: configArrayController,
         withKeyPath: "selectedObjects.@count",
         options: nil)
    self.generateButton.keyEquivalent = "\r"
  }

  // Toggle the state of the buttons depending on the current selection as well as if any required
  // components are still being initialized.
  func updateButtonsState() {
    Thread.doOnMainQueue() {
      let numSelectedConfigs = self.numSelectedConfigs
      let infoExtractorInitialized = self.infoExtractorInitialized
      self.addRemoveSegmentedControl.setEnabled(self.numBazelPackages > 0 && infoExtractorInitialized,
                                           forSegment: SegmentedControlButtonIndex.add.rawValue)
      self.addRemoveSegmentedControl.setEnabled(numSelectedConfigs > 0 && infoExtractorInitialized,
                                           forSegment: SegmentedControlButtonIndex.remove.rawValue)
      self.addRemoveSegmentedControl.setEnabled(numSelectedConfigs == 1 && infoExtractorInitialized,
                                           forSegment: SegmentedControlButtonIndex.action.rawValue)
      self.generateButton.isEnabled = (numSelectedConfigs == 1 && infoExtractorInitialized)
    }
  }

  @IBAction func didClickAddRemoveSegmentedControl(_ sender: NSSegmentedCell) {
    // Ignore mouse up messages.
    if sender.selectedSegment < 0 { return }

    guard let button = SegmentedControlButtonIndex(rawValue: sender.selectedSegment) else {
      assertionFailure("Unexpected add/remove button index \(sender.selectedSegment)")
      return
    }

    switch button {
      case .add:
        didClickAddConfig(sender)
      case .remove:
        didClickRemoveSelectedConfigs(sender)
      case .action:
        didClickAction(sender)
    }
  }

  @IBAction func doGenerate(_ sender: AnyObject?) {
    guard let configName = configArrayController.selectedObjects.first as? String else { return }
    guard requireValidBazel({ self.doGenerate(sender) }) else { return }

    let generatorController = XcodeProjectGenerationProgressViewController()
    generatorController.representedObject = representedObject
    presentAsSheet(generatorController)

    let projectDocument = representedObject as! TulsiProjectDocument
    generatorController.generateProjectForConfigName(configName) { (projectURL: URL?) in
      self.dismiss(generatorController)
      if let projectURL = projectURL {
        LogMessage.postInfo("Opening generated project in Xcode",
                            context: projectDocument.projectName)
        NSWorkspace.shared.open(projectURL)
      }
    }
  }

  @IBAction func didDoubleClickConfigRow(_ sender: NSTableView) {
    guard requireValidBazel({ self.didDoubleClickConfigRow(sender) }) else { return }
    let clickedRow = sender.clickedRow
    guard clickedRow >= 0 else { return }
    let configName = (configArrayController.arrangedObjects as! [String])[clickedRow]
    editConfigNamed(configName)
  }

  @objc func document(_ doc:NSDocument, didSave:Bool, contextInfo: UnsafeMutableRawPointer) {
    if contextInfo == &ProjectEditorConfigManagerViewController.PostSaveContextAddConfig {
      if didSave {
        didClickAddConfig(nil)
      }
    }
  }

  // MARK: - Private methods

  private func didClickAddConfig(_ sender: AnyObject?) {
    guard requireValidBazel({ self.didClickAddConfig(sender) }) else { return }

    let projectDocument = representedObject as! TulsiProjectDocument

    // Adding a config to a project with no bazel packages is disallowed.
    guard let bazelPackages = projectDocument.bazelPackages, !bazelPackages.isEmpty else {
      // This should be prevented by the UI, so spawn a bug message and beep.
      LogMessage.postInfo("Bug: Add config invoked on a project with no packages.")
      NSSound.beep()
      return
    }

    let errorInfo: String
    do {
      let additionalFilePaths = bazelPackages.map() { "\($0)/BUILD" }
      guard let projectName = projectDocument.projectName,
                let generatorConfigFolderURL = projectDocument.generatorConfigFolderURL else {
        projectDocument.save(withDelegate: self,
                             didSave: #selector(ProjectEditorConfigManagerViewController.document(_:didSave:contextInfo:)),
                             contextInfo: &ProjectEditorConfigManagerViewController.PostSaveContextAddConfig)
        return
      }
      let optionSet = projectDocument.optionSet ?? TulsiOptionSet()
      let configDocument = try TulsiGeneratorConfigDocument.makeDocumentWithProjectRuleEntries(projectDocument.ruleInfos,
                                                                                               optionSet: optionSet,
                                                                                               projectName: projectName,
                                                                                               saveFolderURL: generatorConfigFolderURL,
                                                                                               infoExtractor: projectDocument.infoExtractor,
                                                                                               messageLog: projectDocument,
                                                                                               additionalFilePaths: additionalFilePaths,
                                                                                               bazelURL: projectDocument.bazelURL)
      projectDocument.trackChildConfigDocument(configDocument)
      configDocument.delegate = projectDocument
      configDocument.makeWindowControllers()
      configDocument.showWindows()
      return
    } catch let e as NSError {
      errorInfo = e.localizedDescription
    } catch {
      errorInfo = "Unexpected exception"
    }

    let msg = NSLocalizedString("Error_GeneralCriticalFailure",
                                comment: "A general, critical failure without a more fitting descriptive message.")
    LogMessage.postError(msg, details: errorInfo, context: projectDocument.projectName)
    LogMessage.displayPendingErrors()
  }


  /// Verifies that the project's Bazel URL seems valid, forcing the user to select a valid path if
  /// necessary and invoking the given retryHandler once they've finished selection.
  /// Returns true if Bazel is already valid, false if the Bazel picker is being shown.
  private func requireValidBazel(_ retryHandler: @escaping () -> Void) -> Bool {
    let projectDocument = representedObject as! TulsiProjectDocument
    guard let bazelURL = projectDocument.bazelURL,
              FileManager.default.isExecutableFile(atPath: bazelURL.path) else {
      BazelSelectionPanel.beginSheetModalBazelSelectionPanelForWindow(self.view.window!,
                                                                      document: projectDocument) {
        (bazelURL: URL?) in
          if bazelURL != nil {
            retryHandler()
          }
      }
      return false
    }
    return true
  }

  private func didClickRemoveSelectedConfigs(_ sender: AnyObject?) {
    let document = representedObject as! TulsiProjectDocument
    let selectedConfigNames = configArrayController.selectedObjects as! [String]
    document.deleteConfigsNamed(selectedConfigNames)
  }

  private func didClickAction(_ sender: AnyObject?) {
    let selectedConfigNames = configArrayController.selectedObjects as! [String]
    if let configName = selectedConfigNames.first {
      editConfigNamed(configName)
    }
  }

  private func editConfigNamed(_ name: String) {
    let projectDocument = representedObject as! TulsiProjectDocument
    let errorInfo: String
    do {
      let configDocument = try projectDocument.loadConfigDocumentNamed(name) { (_) in
        // Nothing in particular has to be done when the config doc is loaded, the editor UI already
        // handles this via the document's processing state.
      }
      configDocument.makeWindowControllers()
      configDocument.showWindows()
      return
    } catch TulsiProjectDocument.DocumentError.noSuchConfig {
      errorInfo = "No URL for config named '\(name)'"
    } catch TulsiProjectDocument.DocumentError.configLoadFailed(let info) {
      errorInfo = info
    } catch TulsiProjectDocument.DocumentError.invalidWorkspace(let info) {
      errorInfo = "Invalid workspace: \(info)"
    } catch {
      errorInfo = "An unexpected exception occurred while loading config named '\(name)'"
    }
    let msg = NSLocalizedString("Error_ConfigLoadFailed",
                                comment: "Error when a TulsiGeneratorConfig failed to be reloaded.")
    LogMessage.postError(msg, details: errorInfo)
    LogMessage.displayPendingErrors()
  }
}


/// Transformer that returns true if the value is equal to 1.
final class IsOneValueTransformer : ValueTransformer {
  override class func transformedValueClass() -> AnyClass {
    return NSString.self
  }

  override class func allowsReverseTransformation() -> Bool  {
    return false
  }

  override func transformedValue(_ value: Any?) -> Any? {
    if let intValue = value as? Int, intValue == 1 {
      return true
    }
    return false
  }
}
