// 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 XCTest
@testable import TulsiGenerator


/// Base class for test cases utilizing an external Bazel instance.
/// Command line options:
///   -test_bazel: (Required) Path to the Bazel binary to use for testing.
///   -testBazelStartupOptions <string>: Options to be passed to Bazel before the "build" command.
///   -testBazelBuildOptions <string>: Options to be passed to Bazel after the "build" command.
///   -keep_test_output (0 or 1): Retain the test's temporary workspace directory rather than
///       cleaning it up after the test completes.
///   -use_hosted_workspace <path>: Path to a Bazel workspace inside which the test files will be
///       executed. A WORKSPACE file must be present in the given directory.
class BazelIntegrationTestCase: XCTestCase {

  var bazelURL: URL! = nil
  var bazelStartupOptions = [String]()
  var bazelBuildOptions = [String]()
  var workspaceRootURL: URL! = nil
  var packagePathFetcher: BazelWorkspacePathInfoFetcher! = nil
  var localizedMessageLogger: DirectLocalizedMessageLogger! = nil

  private var pathsToCleanOnTeardown = Set<URL>()

  override func setUp() {
    super.setUp()

    let userDefaults = UserDefaults.standard
    guard let bazelPath = userDefaults.string(forKey: "test_bazel") else {
      XCTFail("This test must be launched with test_bazel set to a path to Bazel " +
                  "(e.g., via -test_bazel as a command-line argument)")
      return
    }
    bazelURL = URL(fileURLWithPath: bazelPath)

    let commandLineSplitter = CommandLineSplitter()
    if let startupOptions = userDefaults.string(forKey: "testBazelStartupOptions") {
      guard let splitOptions = commandLineSplitter.splitCommandLine(startupOptions) else {
        XCTFail("Failed to split bazelStartupOptions '\(startupOptions)'")
        return
      }
      bazelStartupOptions = splitOptions
    }
    if let buildOptions = userDefaults.string(forKey: "testBazelBuildOptions") {
      guard let splitOptions = commandLineSplitter.splitCommandLine(buildOptions) else {
        XCTFail("Failed to split bazelBuildOptions '\(buildOptions)'")
        return
      }
      bazelBuildOptions = splitOptions
    }

    if let hostedWorkspaceDirectory = userDefaults.string(forKey: "use_hosted_workspace") {
      workspaceRootURL = URL(fileURLWithPath: hostedWorkspaceDirectory,
                                         isDirectory: true)
    } else {
      let globalTempDir = URL(fileURLWithPath: NSTemporaryDirectory(), isDirectory: true)
      let dirName = "tulsi_\(UUID().uuidString)"
      workspaceRootURL = globalTempDir.appendingPathComponent(dirName, isDirectory: true)

      installWorkspaceFile()
    }

    // Prevent any custom --blazerc startup option to be specified. It should always be /dev/null.
    for startupOption in bazelStartupOptions {
      if (startupOption.hasPrefix("--blazerc=") && startupOption != "--blazerc=/dev/null") {
        fatalError("bazelStartupOptions includes custom blazerc, which is not allowed '\(startupOption)'")
      }
    }
    bazelStartupOptions.append("--blazerc=/dev/null")

    guard let workspaceRootURL = workspaceRootURL else {
      fatalError("Failed to find workspaceRootURL.")
    }

    localizedMessageLogger = DirectLocalizedMessageLogger()
    localizedMessageLogger.startLogging()
    packagePathFetcher = BazelWorkspacePathInfoFetcher(bazelURL: bazelURL,
                                                       workspaceRootURL: workspaceRootURL,
                                                       localizedMessageLogger: localizedMessageLogger)
  }

  override func tearDown() {
    super.tearDown()
    cleanCreatedFiles()
    packagePathFetcher = nil
    if localizedMessageLogger != nil {
      localizedMessageLogger.stopLogging()
    }
    localizedMessageLogger = nil
  }

  /// Copies the .BUILD file bundled under the given name into the test workspace, as well as any
  /// .bzl file with the same root name.
  @discardableResult
  func installBUILDFile(_ fileResourceName: String,
                        intoSubdirectory subdirectory: String? = nil,
                        fromResourceDirectory resourceDirectory: String? = nil,
                        file: StaticString = #file,
                        line: UInt = #line) -> URL? {
    let bundle = Bundle(for: type(of: self))
    guard let buildFileURL = bundle.url(forResource: fileResourceName,
                                                   withExtension: "BUILD",
                                                   subdirectory: resourceDirectory) else {
      XCTFail("Missing required test resource file \(fileResourceName).BUILD",
              file: file,
              line: line)
      return nil
    }

    guard let directoryURL = getWorkspaceDirectory(subdirectory) else { return nil }

    @discardableResult
    func copyFile(_ sourceFileURL: URL, toFileNamed targetName: String) -> URL? {
      let destinationURL = directoryURL.appendingPathComponent(targetName, isDirectory: false)
      do {
        let fileManager = FileManager.default
        if fileManager.fileExists(atPath: destinationURL.path) {
          try fileManager.removeItem(at: destinationURL)
        }
        try fileManager.copyItem(at: sourceFileURL, to: destinationURL)
        pathsToCleanOnTeardown.insert(destinationURL)
      } catch let e as NSError {
        XCTFail("Failed to install '\(sourceFileURL)' to '\(destinationURL)' for test. Error: \(e.localizedDescription)",
                file: file,
                line: line)
        return nil
      }
      return destinationURL
    }

    guard let destinationURL = copyFile(buildFileURL, toFileNamed: "BUILD") else {
      return nil
    }

    if let skylarkFileURL = bundle.url(forResource: fileResourceName,
                                                     withExtension: "bzl",
                                                     subdirectory: resourceDirectory) {
      copyFile(skylarkFileURL, toFileNamed: skylarkFileURL.lastPathComponent)
    }

    return destinationURL
  }

  /// Creates a file in the test workspace with the given contents.
  func makeFileNamed(_ name: String,
                     withData data: Data,
                     inSubdirectory subdirectory: String? = nil,
                     file: StaticString = #file,
                     line: UInt = #line) -> URL? {
    guard let directoryURL = getWorkspaceDirectory(subdirectory,
                                                   file: file,
                                                   line: line) else {
      return nil
    }

    let fileURL = directoryURL.appendingPathComponent(name, isDirectory: false)
    XCTAssertTrue((try? data.write(to: fileURL, options: [.atomic])) != nil,
                  "Failed to write to file at '\(fileURL.path)'",
                  file: file,
                  line: line)
    pathsToCleanOnTeardown.insert(fileURL)
    return fileURL
  }

  /// Creates a file in the test workspace with the given contents.
  func makeFileNamed(_ name: String,
                     withContent content: String = "",
                     inSubdirectory subdirectory: String? = nil,
                     file: StaticString = #file,
                     line: UInt = #line) -> URL? {
    guard let data = (content as NSString).data(using: String.Encoding.utf8.rawValue) else {
      XCTFail("Failed to convert file contents '\(content)' to UTF8-encoded NSData",
              file: file,
              line: line)
      return nil
    }
    return makeFileNamed(name, withData: data, inSubdirectory: subdirectory, file: file, line: line)
  }

  /// Creates a plist file in the test workspace with the given contents.
  @discardableResult
  func makePlistFileNamed(_ name: String,
                          withContent content: [String: Any],
                          inSubdirectory subdirectory: String? = nil,
                          file: StaticString = #file,
                          line: UInt = #line) -> URL? {
    do {
      let data = try PropertyListSerialization.data(fromPropertyList: content,
                                                                      format: .xml,
                                                                      options: 0)
      return makeFileNamed(name, withData: data, inSubdirectory: subdirectory, file: file, line: line)
    } catch let e {
      XCTFail("Failed to serialize content: \(e)", file: file, line: line)
      return nil
    }
  }

  /// Creates a mock xcdatamodel bundle in the given subdirectory.
  @discardableResult
  func makeTestXCDataModel(_ name: String,
                           inSubdirectory subdirectory: String,
                           file: StaticString = #file,
                           line: UInt = #line) -> URL? {
    guard let _ = getWorkspaceDirectory(subdirectory, file: file, line: line) else {
      return nil
    }

    let dataModelPath = "\(subdirectory)/\(name).xcdatamodel"
    guard let datamodelURL = getWorkspaceDirectory(dataModelPath, file: file, line: line) else {
      return nil
    }
    guard let _ = makeFileNamed("elements",
                                withContent: "",
                                inSubdirectory: dataModelPath,
                                file: file,
                                line: line),
          let _ = makeFileNamed("layout",
                                withContent: "",
                                inSubdirectory: dataModelPath,
                                file: file,
                                line: line) else {
      return nil
    }

    return datamodelURL
  }

  /// Creates a workspace-relative directory that will be cleaned up by the test on exit.
  func makeTestSubdirectory(_ subdirectory: String,
                            file: StaticString = #file,
                            line: UInt = #line) -> URL? {
    return getWorkspaceDirectory(subdirectory, file: file, line: line)
  }

  // MARK: - Private methods

  fileprivate func installWorkspaceFile() {
    do {
      try FileManager.default.createDirectory(at: workspaceRootURL,
                                                              withIntermediateDirectories: true,
                                                              attributes: nil)
      pathsToCleanOnTeardown.insert(workspaceRootURL)

      let bundle = Bundle(for: type(of: self))
      guard let fileURL = bundle.url(forResource: "test",
                                                withExtension: "WORKSPACE") else {
        XCTFail("Missing required test.WORKSPACE file")
        return
      }


      let destinationURL = workspaceRootURL.appendingPathComponent("WORKSPACE",
                                                                        isDirectory: false)
      do {
        let fileManager = FileManager.default
        if fileManager.fileExists(atPath: destinationURL.path) {
          try fileManager.removeItem(at: destinationURL)
        }
        try fileManager.copyItem(at: fileURL, to: destinationURL)
        pathsToCleanOnTeardown.insert(destinationURL)
      } catch let e as NSError {
        XCTFail("Failed to install WORKSPACE file '\(fileURL)' to '\(destinationURL)' for test. Error: \(e.localizedDescription)")
        return
      }
    } catch let e as NSError {
      XCTFail("Failed to create temp directory '\(workspaceRootURL!.path)' for test. Error: \(e.localizedDescription)")
    }
  }

  fileprivate func getWorkspaceDirectory(_ subdirectory: String? = nil,
                                     file: StaticString = #file,
                                     line: UInt = #line) -> URL? {
    guard let tempDirectory = workspaceRootURL else {
      XCTFail("Cannot create test workspace directory, workspaceRootURL is nil",
              file: file,
              line: line)
      return nil
    }

    if let subdirectory = subdirectory, !subdirectory.isEmpty {
      let directoryURL = tempDirectory.appendingPathComponent(subdirectory, isDirectory: true)
      pathsToCleanOnTeardown.insert(directoryURL)
      do {
        try FileManager.default.createDirectory(at: directoryURL,
                                                                withIntermediateDirectories: true,
                                                                attributes: nil)
        return directoryURL
      } catch let e as NSError {
        XCTFail("Failed to create directory '\(directoryURL.path)'. Error: \(e.localizedDescription)",
                file: file,
                line: line)
      }
      return nil
    }

    return tempDirectory
  }

  fileprivate func cleanCreatedFiles() {
    if UserDefaults.standard.bool(forKey: "keep_test_output") {
      print("Retaining working files for test \(String(describing: name))")
      for url in pathsToCleanOnTeardown.sorted(by: { $0.path < $1.path }) {
        print("\t\(url)")
      }
      return
    }

    let fileManager = FileManager.default
    // Sort such that deeper paths are removed before their parents.
    let sortedPaths = pathsToCleanOnTeardown.sorted(by: { $1.path < $0.path })
    for url in sortedPaths {
      do {
        try fileManager.removeItem(at: url)
      } catch let e as NSError {
        XCTFail(String(format: "Failed to remove test's temp directory at '%@'. Error: %@",
                       url.path,
                       e))
      }
    }
  }


  /// Override for LocalizedMessageLogger that prints immediately rather than bouncing to the main
  /// thread.
  final class DirectLocalizedMessageLogger: LocalizedMessageLogger {
    var observer: NSObjectProtocol? = nil

    init() {
      super.init(bundle: nil)
    }

    deinit {
      stopLogging()
    }

    func startLogging() {
      observer = NotificationCenter.default.addObserver(forName: NSNotification.Name(rawValue: TulsiMessageNotification),
                                                        object: nil,
                                                        queue: nil) {
        [weak self] (notification: Notification) in
          guard let item = LogMessage(notification: notification) else {
            XCTFail("Invalid message notification received (failed to conver to LogMessage)")
            return
          }
          self?.handleMessage(item)
      }
    }

    func stopLogging() {
      if let observer = self.observer {
        NotificationCenter.default.removeObserver(observer)
      }
    }

    override func warning(_ key: String,
                          comment: String,
                          details: String?,
                          context: String?,
                          values: CVarArg...) {
      LogMessage.postWarning("\(key) - \(values)")
    }

    override func error(_ key: String,
                        comment: String,
                        details: String?,
                        context: String?,
                        values: CVarArg...) {
      XCTFail("> Critical error logged: \(key) - \(values)")
    }

    fileprivate func handleMessage(_ item: LogMessage) {
      switch item.level {
        case .Error:
          XCTFail("> Critical error logged: \(item.message)\nDetails:\n\(String(describing: item.details))")
        case .Warning:
          print("> W: \(item.message)")
        case .Info:
          print("> I: \(item.message)")
        case .Syslog:
          print("> S: \(item.message)")
      }
    }
  }
}
