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

    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.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 project = projectDocument.project {
      config = config.configByResolvingInheritedSettingsFromProject(project)
    }
    if let extraFlags = arguments.buildOptions {
      config.options[.BazelBuildOptionsDebug].appendProjectValue(extraFlags)
      config.options[.BazelBuildOptionsRelease].appendProjectValue(extraFlags)
    }

    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
    }

    if let announcementIdToMarkRead = arguments.announcementId {
      guard
        let announcement = try Announcement.loadAnnouncement(byId: announcementIdToMarkRead)
      else {
        throw HeadlessModeError.invalidAnnouncementId
      }

      announcement.recordDismissal()
      print("\(announcementIdToMarkRead) has been marked read and will not appear again.")
    }

    let announcement = try? Announcement.getNextUnreadAnnouncement()

    if let announcementToDisplay = announcement, announcementToDisplay.shouldAppearAtTopOfCLIOutput
    {
      print(announcementToDisplay.createCLIOutput())
    }

    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:
        throw HeadlessModeError.generationFailed
    }

    if let announcementToDisplay = announcement,
      !announcementToDisplay.shouldAppearAtTopOfCLIOutput
    {
      print(announcementToDisplay.createCLIOutput())
    }
  }

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