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


// Base class for end-to-end tests that generate xcodeproj bundles and validate them against golden
// versions.
class EndToEndIntegrationTestCase : BazelIntegrationTestCase {
  enum Error: Swift.Error {
    /// A subdirectory for the Xcode project could not be created.
    case testSubdirectoryNotCreated
    /// The Xcode project could not be generated.
    case projectGenerationFailure(String)
    /// Unable to execute user_build.py script.
    case userBuildScriptInvocationFailure(String)
  }

  let extraDebugFlags = ["--define=TULSI_TEST=dbg"]
  let extraReleaseFlags = ["--define=TULSI_TEST=rel"]
  let fakeBazelURL = URL(fileURLWithPath: "/fake/tulsi_test_bazel", isDirectory: false)
  let testTulsiVersion = "9.99.999.9999"

  final func validateDiff(_ diffLines: [String], file: StaticString = #file, line: UInt = #line) {
    for diff in diffLines {
      XCTFail(diff, file: file, line: line)
    }
  }

  final func diffProjectAt(_ projectURL: URL,
                           againstGoldenProject resourceName: String,
                           file: StaticString = #file,
                           line: UInt = #line) -> [String] {
    guard let hashing = ProcessInfo.processInfo.environment["SWIFT_DETERMINISTIC_HASHING"],
        hashing == "1" else {
      XCTFail("Must define environment variable \"SWIFT_DETERMINISTIC_HASHING=1\", or golden tests will fail.")
      return []
    }
    let bundle = Bundle(for: type(of: self))
    let goldenProjectURL = workspaceRootURL.appendingPathComponent(fakeBazelWorkspace
                                                                       .resourcesPathBase,
                                                                   isDirectory: true)
        .appendingPathComponent("GoldenProjects/\(resourceName).xcodeproj", isDirectory: true)
    guard FileManager.default.fileExists(atPath: goldenProjectURL.path) else {
      assertionFailure("Missing required test resource file \(resourceName).xcodeproj")
      XCTFail("Missing required test resource file \(resourceName).xcodeproj",
              file: file,
              line: line)
      return []
    }

    var diffOutput = [String]()
    let semaphore = DispatchSemaphore(value: 0)
    let process = ProcessRunner.createProcess("/usr/bin/diff",
                                              arguments: ["-r",
                                                          // For the sake of simplicity in
                                                          // maintaining the golden data, copied
                                                          // Tulsi artifacts are assumed to have
                                                          // been installed correctly.
                                                          "--exclude=.tulsi",
                                                          projectURL.path,
                                                          goldenProjectURL.path]) {
      completionInfo in
        defer {
          semaphore.signal()
        }
        if let stdout = NSString(data: completionInfo.stdout, encoding: String.Encoding.utf8.rawValue) {
          diffOutput = stdout.components(separatedBy: "\n").filter({ !$0.isEmpty })
        } else {
          XCTFail("No output received for diff command", file: file, line: line)
        }
    }
    process.currentDirectoryPath = workspaceRootURL.path
    process.launch()

    _ = semaphore.wait(timeout: DispatchTime.distantFuture)
    return diffOutput
  }

  final func copyOutput(source: URL, outputDir: String) throws {
    if testUndeclaredOutputsDir != nil {
      guard let testOutputURL = makeTestSubdirectory(outputDir,
                                                     rootDirectory: testUndeclaredOutputsDir,
                                                     cleanupOnTeardown: false) else {
        throw Error.testSubdirectoryNotCreated
      }
      let testOutputProjURL = testOutputURL.appendingPathComponent(source.lastPathComponent)
      if FileManager.default.fileExists(atPath: testOutputProjURL.path) {
        try FileManager.default.removeItem(at: testOutputProjURL)
      }
      try FileManager.default.copyItem(at: source, to: testOutputProjURL)
    }
  }

  final func validateBuildCommandForProject(_ projectURL: URL,
                                            swift: Bool = false,
                                            options: TulsiOptionSet = TulsiOptionSet(),
                                            targets: [String]) throws {
    let actualDebug = try userBuildCommandForProject(projectURL, release: false, targets: targets)
    let actualRelease = try userBuildCommandForProject(projectURL, release: true, targets: targets)
    let (debug, release) = expectedBuildCommands(swift: swift, options: options, targets: targets)

    XCTAssertEqual(actualDebug, debug)
    XCTAssertEqual(actualRelease, release)
  }

  final func expectedBuildCommands(swift: Bool,
                                   options: TulsiOptionSet,
                                   targets: [String]) -> (String, String) {
    let provider = BazelSettingsProvider(universalFlags: bazelUniversalFlags)
    let features = BazelBuildSettingsFeatures.enabledFeatures(options: options)
    let dbg = provider.tulsiFlags(hasSwift: swift, options: options, features: features).debug
    let rel = provider.tulsiFlags(hasSwift: swift, options: options, features: features).release

    let config: PlatformConfiguration
    if let identifier = options[.ProjectGenerationPlatformConfiguration].commonValue,
      let parsedConfig = PlatformConfiguration(identifier: identifier) {
      config = parsedConfig
    } else {
      config = PlatformConfiguration.defaultConfiguration
    }

    func buildCommand(extraBuildFlags: [String], tulsiFlags: BazelFlags) -> String {
      var args = [fakeBazelURL.path]
      args.append(contentsOf: bazelStartupOptions)
      args.append(contentsOf: tulsiFlags.startup)
      args.append("build")
      args.append(contentsOf: extraBuildFlags)
      args.append(contentsOf: bazelBuildOptions)
      args.append(contentsOf: config.bazelFlags)
      args.append(contentsOf: tulsiFlags.build)
      args.append("--tool_tag=tulsi:user_build")
      args.append(contentsOf: targets)

      return args.map { $0.escapingForShell }.joined(separator: " ")
    }

    let debugCommand = buildCommand(extraBuildFlags: extraDebugFlags, tulsiFlags: dbg)
    let releaseCommand = buildCommand(extraBuildFlags: extraReleaseFlags, tulsiFlags: rel)

    return (debugCommand, releaseCommand)
  }

  final func userBuildCommandForProject(_ projectURL: URL,
                                        release: Bool = false,
                                        targets: [String],
                                        file: StaticString = #file,
                                        line: UInt = #line) throws -> String {
    let expectedScriptURL = projectURL.appendingPathComponent(".tulsi/Scripts/user_build.py",
                                                               isDirectory: false)
    let fileManager = FileManager.default

    guard fileManager.fileExists(atPath: expectedScriptURL.path) else {
      throw Error.userBuildScriptInvocationFailure(
          "user_build.py script not found: expected at path \(expectedScriptURL.path)")
    }

    var output = "<none>"
    let semaphore = DispatchSemaphore(value: 0)
    var args = [
        "--norun",
    ]
    if release {
      args.append("--release")
    }
    args.append(contentsOf: targets)

    let process = ProcessRunner.createProcess(
      expectedScriptURL.path,
      arguments: args,
      messageLogger: localizedMessageLogger
    ) { completionInfo in
        defer {
          semaphore.signal()
        }
        let exitcode = completionInfo.terminationStatus
        guard exitcode == 0 else {
          let stderr =
            String(data: completionInfo.stderr, encoding: .utf8) ?? "<no stderr>"
          XCTFail("user_build.py returned \(exitcode). stderr: \(stderr)", file: file, line: line)
          return
        }
        if let stdout = String(data: completionInfo.stdout, encoding: .utf8)?.trimmingCharacters(in: CharacterSet.whitespacesAndNewlines),
            !stdout.isEmpty {
          output = stdout
        } else {
          let stderr =
              String(data: completionInfo.stderr, encoding: .utf8) ?? "<no stderr>"
          XCTFail("user_build.py had no stdout. stderr: \(stderr)", file: file, line: line)
        }
    }
    process.currentDirectoryPath = workspaceRootURL.path
    process.launch()

    _ = semaphore.wait(timeout: DispatchTime.distantFuture)
    return output
  }

  final func generateProjectNamed(_ projectName: String,
                                  buildTargets: [RuleInfo],
                                  pathFilters: [String],
                                  additionalFilePaths: [String] = [],
                                  outputDir: String,
                                  options: TulsiOptionSet = TulsiOptionSet()) throws -> URL {
    if !bazelStartupOptions.isEmpty {
      let startupFlags = bazelStartupOptions.joined(separator: " ")
      options[.BazelBuildStartupOptionsDebug].projectValue = startupFlags
      options[.BazelBuildStartupOptionsRelease].projectValue = startupFlags
    }

    let debugBuildOptions = extraDebugFlags + bazelBuildOptions
    let releaseBuildOptions = extraReleaseFlags + bazelBuildOptions

    options[.BazelBuildOptionsDebug].projectValue = debugBuildOptions.joined(separator: " ")
    options[.BazelBuildOptionsRelease].projectValue = releaseBuildOptions.joined(separator: " ")

    let bazelURLParam = TulsiParameter(value: fakeBazelURL, source: .explicitlyProvided)
    let config = TulsiGeneratorConfig(projectName: projectName,
                                      buildTargets: buildTargets,
                                      pathFilters: Set<String>(pathFilters),
                                      additionalFilePaths: additionalFilePaths,
                                      options: options,
                                      bazelURL: bazelURLParam)

    guard let outputFolderURL = makeXcodeProjPath(outputDir) else {
      throw Error.testSubdirectoryNotCreated
    }

    let projectGenerator = TulsiXcodeProjectGenerator(workspaceRootURL: workspaceRootURL,
                                                      config: config,
                                                      extractorBazelURL: bazelURL,
                                                      tulsiVersion: testTulsiVersion)
    // Bazel built-in preprocessor defines are suppressed in order to prevent any
    // environment-dependent variables from mismatching the golden data.
    projectGenerator.xcodeProjectGenerator.suppressCompilerDefines = true
    // Don't update shell command utilities.
    projectGenerator.xcodeProjectGenerator.suppressUpdatingShellCommands = true
    // The username is forced to a known value.
    projectGenerator.xcodeProjectGenerator.usernameFetcher = { "_TEST_USER_" }
    // The workspace symlink is forced to a known value.
    projectGenerator.xcodeProjectGenerator.redactWorkspaceSymlink = true
    let errorInfo: String
    do {
      let generatedProjURL = try projectGenerator.generateXcodeProjectInFolder(outputFolderURL)
      try copyOutput(source: generatedProjURL, outputDir: outputDir)
      return generatedProjURL
    } catch TulsiXcodeProjectGenerator.GeneratorError.unsupportedTargetType(let targetType) {
      errorInfo = "Unsupported target type: \(targetType)"
    } catch TulsiXcodeProjectGenerator.GeneratorError.serializationFailed(let details) {
      errorInfo = "General failure: \(details)"
    } catch let error {
      errorInfo = "Unexpected failure: \(error)"
    }
    throw Error.projectGenerationFailure(errorInfo)
  }
}
