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

/// Base class for test cases utilizing an external Bazel instance.
class BazelIntegrationTestCase: XCTestCase {

  var bazelURL: URL! = nil
  var bazelStartupOptions = [String]()
  var bazelBuildOptions = [String]()
  var runfilesURL: URL! = nil
  var fakeBazelWorkspace: BazelFakeWorkspace! = nil
  var bazelUniversalFlags = BazelFlags()
  var workspaceRootURL: URL! = nil
  var testUndeclaredOutputsDir: URL? = nil
  var workspaceInfoFetcher: BazelWorkspacePathInfoFetcher! = nil
  var localizedMessageLogger: DirectLocalizedMessageLogger! = nil

  private var pathsToCleanOnTeardown = Set<URL>()

  override func setUp() {
    super.setUp()

    guard let test_srcdir = ProcessInfo.processInfo.environment["TEST_SRCDIR"] else {
      XCTFail("This test must be run as a bazel test and/or must define $TEST_SRCDIR.")
      return
    }
    runfilesURL = URL(fileURLWithPath: test_srcdir)

    let tempdir = ProcessInfo.processInfo.environment["TEST_TMPDIR"] ?? NSTemporaryDirectory()
    let tempdirURL = URL(fileURLWithPath: tempdir,
                         isDirectory: true)
    fakeBazelWorkspace = BazelFakeWorkspace(runfilesURL: runfilesURL,
                                            tempDirURL: tempdirURL).setup()
    pathsToCleanOnTeardown.formUnion(fakeBazelWorkspace.pathsToCleanOnTeardown)
    workspaceRootURL = fakeBazelWorkspace.workspaceRootURL
    bazelURL = fakeBazelWorkspace.bazelURL

    // Add any build options specific to the fakeBazelWorkspace.
    bazelBuildOptions.append(contentsOf: fakeBazelWorkspace.extraBuildFlags)

    if let testOutputPath = ProcessInfo.processInfo.environment["TEST_UNDECLARED_OUTPUTS_DIR"] {
      testUndeclaredOutputsDir = URL(fileURLWithPath: testOutputPath, isDirectory: true)
    }

    // Source is being copied outside of the normal workspace, so status commands won't work.
    bazelBuildOptions.append("--workspace_status_command=/usr/bin/true")

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

    // Prevent any custom --*_minimum_os build option to be specified for tests, as this will
    // effectively remove the reproduceability of the generated projects.
    for bazelBuildOption in bazelBuildOptions {
      if (bazelBuildOption.hasPrefix("--ios_minimum_os") ||
        bazelBuildOption.hasPrefix("--macos_minimum_os") ||
        bazelBuildOption.hasPrefix("--tvos_minimum_os")  ||
        bazelBuildOption.hasPrefix("--watchos_minimum_os")) {
        fatalError("testBazelBuildOptions includes minimum deployment " +
            "version '\(bazelBuildOption)'. Setting this value is not allowed.")
      }
    }

    // Set the default deployment versions for all platforms to prevent different Xcode from
    // producing different generated projects that only differ on *_DEPLOYMENT_VERSION values.
    bazelBuildOptions.append("--ios_minimum_os=8.0")
    bazelBuildOptions.append("--macos_minimum_os=10.10")
    bazelBuildOptions.append("--tvos_minimum_os=10.0")
    bazelBuildOptions.append("--watchos_minimum_os=3.0")

    // Explicitly set Xcode version to use. Must use the same version or the golden files
    // won't match.
    bazelBuildOptions.append("--xcode_version=10.1")

    // Disable the Swift worker as it adds extra dependencies.
    bazelBuildOptions.append("--define=RULES_SWIFT_BUILD_DUMMY_WORKER=1")

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

    let bundle = Bundle(for: TulsiXcodeProjectGenerator.self)
    let bazelWorkspace =
      bundle.url(forResource: "WORKSPACE", withExtension: nil)!.deletingLastPathComponent()

    bazelUniversalFlags = BazelFlags(build: [
        "--override_repository=tulsi=\(bazelWorkspace.path)"
    ])

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

  override func tearDown() {
    super.tearDown()
    cleanCreatedFiles()
    workspaceInfoFetcher = 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? {
    guard var resourceDirectoryURL = getWorkspaceDirectory(fakeBazelWorkspace.resourcesPathBase)
        else { return nil }
    if let resourceDirectory = resourceDirectory {
      resourceDirectoryURL.appendPathComponent(resourceDirectory, isDirectory: true)
    }
    let buildFileURL = resourceDirectoryURL.appendingPathComponent("\(fileResourceName).BUILD",
                                                                   isDirectory: false)

    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
    }

    let skylarkFileURL = resourceDirectoryURL.appendingPathComponent("\(fileResourceName).bzl")
    if FileManager.default.fileExists(atPath: skylarkFileURL.path) {
      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.
  @discardableResult
  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,
                            rootDirectory: URL? = nil,
                            cleanupOnTeardown: Bool = true,
                            file: StaticString = #file,
                            line: UInt = #line) -> URL? {
    return getWorkspaceDirectory(subdirectory,
                                 rootDirectory: rootDirectory,
                                 cleanupOnTeardown: cleanupOnTeardown,
                                 file: file,
                                 line: line)
  }

  func makeXcodeProjPath(_ subdirectory: String,
                        file: StaticString = #file,
                        line: UInt = #line) -> URL? {
    return getWorkspaceDirectory(subdirectory, file: file, line: line)
  }

  // MARK: - Private methods

  fileprivate func getWorkspaceDirectory(_ subdirectory: String? = nil,
                                         rootDirectory: URL? = nil,
                                         cleanupOnTeardown: Bool = true,
                                         file: StaticString = #file,
                                         line: UInt = #line) -> URL? {
    guard let tempDirectory = rootDirectory ?? 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)
      if cleanupOnTeardown {
        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() {
    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: Bundle(for: TulsiXcodeProjectGenerator.self))
    }

    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 {
            guard !(notification.userInfo?["displayErrors"] as? Bool ?? false) else {
              return
            }

            XCTFail("Invalid message notification received (failed to convert to LogMessage)")
            return
          }
          self?.handleMessage(item)
      }
    }

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

    fileprivate func handleMessage(_ item: LogMessage) {
      switch item.level {
        case .Error:
          if let details = item.details {
            print("> Critical error logged: \(item.message)\nDetails:\n\(details)")
          } else {
            print("> Critical error logged: \(item.message)")
          }
        case .Warning:
          print("> W: \(item.message)")
        case .Info:
          print("> I: \(item.message)")
        case .Syslog:
          print("> S: \(item.message)")
        case .Debug:
          print("> D: \(item.message)")
      }
    }
  }
}
