// 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] {
    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)
  }
}
