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


/// Provides functionality to generate an Xcode project from a TulsiGeneratorConfig
struct HeadlessXcodeProjectGenerator {
  let arguments: TulsiCommandlineParser.Arguments

  /// Performs project generation.
  func generate() throws {
    TulsiProjectDocument.showAlertsOnErrors = false
    TulsiProjectDocument.suppressWORKSPACECheck = arguments.suppressWORKSPACECheck

    let explicitBazelURL: URL?
    if let bazelPath = arguments.bazel {
      if !FileManager.default.isExecutableFile(atPath: bazelPath) {
        throw HeadlessModeError.invalidBazelPath
      }
      explicitBazelURL = URL(fileURLWithPath: bazelPath)
      TulsiProjectDocument.suppressRuleEntryUpdateOnLoad = true
    } else {
      explicitBazelURL = nil
    }

    defer {
      TulsiProjectDocument.showAlertsOnErrors = true
      TulsiProjectDocument.suppressWORKSPACECheck = false
      TulsiProjectDocument.suppressRuleEntryUpdateOnLoad = false
    }

    guard let configPath = arguments.generatorConfig else {
      fatalError("HeadlessXcodeProjectGenerator invoked without a valid generatorConfig")
    }

    let (projectURL, configURL, defaultOutputFolderURL) = try resolveConfigPath(configPath)

    let documentController = NSDocumentController.shared()
    let doc: NSDocument
    do {
      doc = try documentController.makeDocument(withContentsOf: projectURL,
                                                                 ofType: "com.google.tulsi.project")
    } catch TulsiProjectDocument.DocumentError.invalidWorkspace(let info) {
      throw HeadlessModeError.invalidProjectFileContents("Failed to load project due to invalid workspace: \(info)")
    } catch let e as NSError {
      throw HeadlessModeError.invalidProjectFileContents("Failed to load project due to unexpected exception: \(e)")
    } catch {
      throw HeadlessModeError.invalidProjectFileContents("Failed to load project due to unexpected exception.")
    }
    guard let projectDocument = doc as? TulsiProjectDocument else {
      throw HeadlessModeError.invalidProjectFileContents("\(doc) is not of the expected type.")
    }

    let outputFolderURL: URL
    if let option = arguments.outputFolder {
      outputFolderURL = URL(fileURLWithPath: option, isDirectory: true)
    } else if let defaultOutputFolderURL = defaultOutputFolderURL {
      outputFolderURL = defaultOutputFolderURL
    } else {
      throw HeadlessModeError.explicitOutputOptionRequired
    }

    var config = try loadConfig(configURL, bazelURL: explicitBazelURL)
    config = config.configByAppendingPathFilters(arguments.additionalPathFilters)

    if let projectOptionSet = projectDocument.optionSet {
      config = config.configByResolvingInheritedOptions(projectOptionSet)
    }

    let workspaceRootURL: URL
    let projectWorkspaceRootURL = projectDocument.workspaceRootURL
    if let workspaceRootOverride = arguments.workspaceRootOverride {
      workspaceRootURL = URL(fileURLWithPath: workspaceRootOverride, isDirectory: true)
      if !isExistingDirectory(workspaceRootURL) {
        throw HeadlessModeError.invalidWorkspaceRootOverride
      }
      if projectWorkspaceRootURL != nil {
        print("Overriding project workspace root (\(projectWorkspaceRootURL!.path)) with " +
            "command-line parameter (\(workspaceRootOverride))")
      }
    } else {
      guard let projectWorkspaceRootURL = projectWorkspaceRootURL else {
        throw HeadlessModeError.invalidProjectFileContents("Invalid workspaceRoot")
      }
      workspaceRootURL = projectWorkspaceRootURL as URL
    }

    print("Generating project into '\(outputFolderURL.path)' using:\n" +
              "\tconfig at '\(configURL.path)'\n" +
              "\tBazel workspace at '\(workspaceRootURL.path)'\n" +
              "\tBazel at '\(config.bazelURL.path)'.\n" +
              "This may take a while.")

    let result = TulsiGeneratorConfigDocument.generateXcodeProjectInFolder(outputFolderURL,
                                                                           withGeneratorConfig: config,
                                                                           workspaceRootURL: workspaceRootURL,
                                                                           messageLog: nil)
    switch result {
      case .success(let url):
        print("Generated project at \(url.path)")
        if arguments.openXcodeOnSuccess {
          print("Opening generated project in Xcode")
          NSWorkspace.shared().open(url)
        }
      case .failure(let errorInfo):
        throw HeadlessModeError.generationFailed(errorInfo)
    }
  }

  // MARK: - Private methods

  private func resolveConfigPath(_ path: String) throws -> (projectURL: URL,
                                                          configURL: URL,
                                                          defaultOutputFolderURL: URL?) {
    let tulsiProjExtension = TulsiProjectDocument.getTulsiBundleExtension()
    let components = path.components(separatedBy: ":")
    if components.count == 2 {
      var pathString = components[0] as NSString
      let projectExtension = pathString.pathExtension
      if projectExtension != tulsiProjExtension {
        pathString = pathString.appendingPathExtension(tulsiProjExtension)! as NSString
      }
      let projectURL = URL(fileURLWithPath: pathString as String)
      let (configURL, defaultOutputFolderURL) = try locateConfigNamed(components[1],
                                                                      inTulsiProject: pathString as String)
      return (projectURL, configURL, defaultOutputFolderURL)
    }

    var pathString = path as NSString
    let pathExtension = pathString.pathExtension
    var isProject = pathExtension == tulsiProjExtension
    if !isProject && pathExtension.isEmpty {
      // See if the user provided a Tulsiproj bundle without the extension or if there is a
      // tulsiproj bundle with the same name as the given directory.
      let projectPath = pathString.appendingPathExtension(tulsiProjExtension)!
      if isExistingDirectory(URL(fileURLWithPath: projectPath, isDirectory: true)) {
        isProject = true
        pathString = projectPath as NSString
      } else {
        let projectName = (pathString.lastPathComponent as NSString).appendingPathExtension(tulsiProjExtension)!
        let projectWithinPath = pathString.appendingPathComponent(projectName)
        if isExistingDirectory(URL(fileURLWithPath: projectWithinPath, isDirectory: true)) {
          isProject = true
          pathString = projectWithinPath as NSString
        }
      }
    }
    if isProject {
      let project = pathString.lastPathComponent as NSString
      let projectName = project.deletingPathExtension
      let (configURL, defaultOutputFolderURL) = try locateConfigNamed(projectName,
                                                                      inTulsiProject: pathString as String)
      let projectURL = URL(fileURLWithPath: pathString as String)
      return (projectURL, configURL, defaultOutputFolderURL)
    }

    throw HeadlessModeError.invalidConfigPath("The given config is invalid")
  }

  private func locateConfigNamed(_ configName: String,
                                 inTulsiProject tulsiProj: String) throws -> (configURL: URL, defaultOutputFolderURL: URL?) {
    let tulsiProjectURL = URL(fileURLWithPath: tulsiProj, isDirectory: true)
    if !isExistingDirectory(tulsiProjectURL) {
      throw HeadlessModeError.invalidConfigPath("The given Tulsi project does not exist")
    }

    let configDirectoryURL = tulsiProjectURL.appendingPathComponent(TulsiProjectDocument.ProjectConfigsSubpath)
    if !isExistingDirectory(configDirectoryURL) {
      throw HeadlessModeError.invalidConfigPath("The given Tulsi project does not contain any configs")
    }

    let configFilename: String
    if configName.hasSuffix(TulsiGeneratorConfig.FileExtension) {
      configFilename = configName
    } else {
      configFilename = "\(configName).\(TulsiGeneratorConfig.FileExtension)"
    }

    let configFileURL = configDirectoryURL.appendingPathComponent(configFilename)
    if FileManager.default.isReadableFile(atPath: configFileURL.path) {
      return (configFileURL, tulsiProjectURL.deletingLastPathComponent())
    }
    throw HeadlessModeError.invalidConfigPath("The given Tulsi project does not contain a Tulsi config named \(configName).")
  }

  private func isExistingDirectory(_ url: URL) -> Bool {
    var isDirectory = ObjCBool(false)
    if !FileManager.default.fileExists(atPath: url.path, isDirectory: &isDirectory) {
      return false
    }
    return isDirectory.boolValue
  }

  private func loadConfig(_ url: URL, bazelURL: URL?) throws -> TulsiGeneratorConfig {
    let config: TulsiGeneratorConfig
    do {
      config = try TulsiGeneratorConfig.load(url, bazelURL: bazelURL)
    } catch TulsiGeneratorConfig.ConfigError.badInputFilePath {
      throw HeadlessModeError.invalidConfigFileContents("Failed to read config file at \(url.path)")
    } catch TulsiGeneratorConfig.ConfigError.failedToReadAdditionalOptionsData(let info) {
      throw HeadlessModeError.invalidConfigFileContents("Failed to read per-user config file: \(info)")
    } catch TulsiGeneratorConfig.ConfigError.deserializationFailed(let info) {
      throw HeadlessModeError.invalidConfigFileContents("Config file at \(url.path) is invalid: \(info)")
    } catch {
      throw HeadlessModeError.invalidConfigFileContents("Unexpected exception reading config file at \(url.path)")
    }

    if !config.bazelURL.isFileURL {
      throw HeadlessModeError.invalidBazelPath
    }
    return config
  }
}
