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


// Parent class for end to end tests that generate an xcodeproj with the Tulsi binary and verify the
// generated xcodeproj by running the projects unit tests.
class TulsiEndToEndTest: BazelIntegrationTestCase {
  fileprivate static let simulatorName = "tulsie2e-\(UUID().uuidString.prefix(8))"
  fileprivate static let targetVersion = "12.2"

  let fileManager = FileManager.default
  var runfilesWorkspaceURL: URL! = nil

  // Calling XCTFail() in a setUp() function will cause the test to crash and hide any logs.
  // Instead, explicitly log that a set up error occured.
  static func setUpFailure(_ msg: String) {
    print("SETUP FAILURE: \(msg)")
  }

  // Creates a new simulator, for use with testing generated projects, before any tests run.
  override class func setUp() {
    super.setUp()

    let targetDevice = "iPhone XS"
    let deviceName = targetDevice.replacingOccurrences(of: " ", with: "-")
    let deviceVersion = TulsiEndToEndTest.targetVersion.replacingOccurrences(of: ".", with: "-")
    let typeId = "com.apple.CoreSimulator.SimDeviceType.\(deviceName)"
    let runtimeId = "com.apple.CoreSimulator.SimRuntime.iOS-\(deviceVersion)"
    let completionInfo = ProcessRunner.launchProcessSync("/usr/bin/xcrun",
                                                         arguments: ["simctl",
                                                                     "create",
                                                                     TulsiEndToEndTest.simulatorName,
                                                                     typeId,
                                                                     runtimeId])

    if completionInfo.terminationStatus != 0 {
      if let stderr = String(data: completionInfo.stderr, encoding: .utf8), !stderr.isEmpty {
        TulsiEndToEndTest.setUpFailure("\(completionInfo.commandlineString) failed with error: \(stderr)")
      } else {
        TulsiEndToEndTest.setUpFailure("\(completionInfo.commandlineString) encountered an error. Exit code \(completionInfo.terminationStatus).")
      }
    }

    // 'simctl' should output the UUID of the new simulator if it was created successfully.
    if let stdout = String(data: completionInfo.stdout, encoding: .utf8), stdout.isEmpty {
      TulsiEndToEndTest.setUpFailure("No UUID was ouputted for newly created simulator.")
    }
  }

  // Deletes the simulator created after all tests have run.
  override class func tearDown() {
    super.tearDown()

    let completionInfo = ProcessRunner.launchProcessSync("/usr/bin/xcrun",
                                                         arguments: ["simctl",
                                                                     "delete",
                                                                     TulsiEndToEndTest.simulatorName])

    if let error = String(data: completionInfo.stderr, encoding: .utf8), !error.isEmpty {
      print("""
            \(completionInfo.commandlineString) failed with exit code: \(completionInfo.terminationStatus)
            Error: \(error)
            """)
    }
  }

  // Unzips Tulsi and boots the simulator before each test case.
  override func setUp() {
    super.setUp()
    super.continueAfterFailure = false
    runfilesWorkspaceURL = fakeBazelWorkspace.runfilesWorkspaceURL
    XCTAssertNotNil(runfilesWorkspaceURL, "runfilesWorkspaceURL must be not be nil after setup.")

    // Extracting only needs to be done once but we can't do this during the class 'setUp' function
    // because we need access to instance variables. Instead, check here if Tulsi has already been
    // extracted.
    if !fileManager.fileExists(atPath: workspaceRootURL.appendingPathComponent("Tulsi.app").path) {
      // Unzip the Tulsi.app bundle to the temp space.
      let tulsiZipPath = "tulsi.zip"
      let tulsiZipURL = runfilesWorkspaceURL.appendingPathComponent(tulsiZipPath, isDirectory: false)
      let completionInfo = ProcessRunner.launchProcessSync("/usr/bin/unzip",
                                                           arguments: [tulsiZipURL.path,
                                                                       "-d",
                                                                       workspaceRootURL.path])

      if let error = String(data: completionInfo.stderr, encoding: .utf8), !error.isEmpty {
        TulsiEndToEndTest.setUpFailure(error)
      }
    }

    // Boots the simulator in the background.
    self.runSimctlCommand("boot", onSimulator: TulsiEndToEndTest.simulatorName)
  }

  // Shuts down and erases the simulator after each test case.
  override func tearDown() {
    super.tearDown()
    self.runSimctlCommand("shutdown", onSimulator: TulsiEndToEndTest.simulatorName)
    self.runSimctlCommand("erase", onSimulator: TulsiEndToEndTest.simulatorName)
  }

  // Takes a short path to data files and adds them to the fake Bazel workspace.
  func copyDataToFakeWorkspace(_ path: String) -> Bool {
    let sourceURL = runfilesWorkspaceURL.appendingPathComponent(path, isDirectory: false)
    let destURL = workspaceRootURL.appendingPathComponent(path, isDirectory: false)
    do {
      if(!fileManager.fileExists(atPath: sourceURL.path)) {
        XCTFail("Source file  \(sourceURL.path) does not exist.")
      }
      if fileManager.fileExists(atPath: destURL.path) {
        try fileManager.removeItem(at: destURL)
      }

      // Symlinks cause issues with Tulsi and Storyboards so must deep copy any data files.
      try fileManager.deepCopyItem(at: sourceURL, to: destURL)
      return true
    } catch let e as NSError {
      print(e.localizedDescription)
      return false
    }
  }

  // Runs the Tulsi binary with the given Tulsi project and config to generate an Xcode project.
  func generateXcodeProject(tulsiProject path: String, config: String) -> URL{
    let tulsiBinURL = workspaceRootURL.appendingPathComponent("Tulsi.app/Contents/MacOS/Tulsi", isDirectory: false)
    XCTAssert(fileManager.fileExists(atPath: tulsiBinURL.path), "Tulsi binary is missing.")

    let projectURL = workspaceRootURL.appendingPathComponent(path, isDirectory: true)
    XCTAssert(fileManager.fileExists(atPath: projectURL.path), "Tulsi project is missing.")
    let configPath = projectURL.path + ":" + config

    // Generate Xcode project with Tulsi.
    let completionInfo = ProcessRunner.launchProcessSync(tulsiBinURL.path,
                                                         arguments: ["--",
                                                                     "--genconfig",
                                                                     configPath,
                                                                     "--outputfolder",
                                                                     workspaceRootURL.path,
                                                                     "--bazel",
                                                                     bazelURL.path,
                                                                     "--no-open-xcode"])

    if let stdoutput = String(data: completionInfo.stdout, encoding: .utf8) {
      print(stdoutput)
    }
    if let erroutput = String(data: completionInfo.stderr, encoding: .utf8) {
      print(erroutput)
    }

    let filename = TulsiGeneratorConfig.sanitizeFilename("\(config).xcodeproj")
    let xcodeProjectURL = workspaceRootURL.appendingPathComponent(filename, isDirectory: true)

    // Remove Xcode project after each test method.
    addTeardownBlock {
      do {
        if self.fileManager.fileExists(atPath: xcodeProjectURL.path) {
          try self.fileManager.removeItem(at: xcodeProjectURL)
          XCTAssertFalse(self.fileManager.fileExists(atPath: xcodeProjectURL.path))
        }
      } catch {
          XCTFail("Error while deleting generated Xcode project: \(error)")
      }
    }

    return xcodeProjectURL
  }

  /// Returns the "json" style dictionary of a project.
  ///
  /// - Parameters:
  ///   - xcodeProjectURL: URL of project.
  /// - Returns
  ///   - Dictionary of string to json style objects.
  fileprivate func xcodeProjectDictionary(_ xcodeProjectURL: URL) -> [String: Any]? {
    let completionInfo = ProcessRunner.launchProcessSync("/usr/bin/xcodebuild",
                                                         arguments: ["-list",
                                                                     "-json",
                                                                     "-project",
                                                                     xcodeProjectURL.path])
    guard let stdoutput = String(data: completionInfo.stdout, encoding: .utf8),
         !stdoutput.isEmpty else {
      if let error = String(data: completionInfo.stderr, encoding: .utf8), !error.isEmpty {
        XCTFail(error)
      } else {
        XCTFail("Xcode project tests did not return success.")
      }
      return nil
    }
    guard let jsonDeserialized = try? JSONSerialization.jsonObject(with: completionInfo.stdout, options: []) else {
      XCTFail("Unable to decode from json: \(stdoutput)")
      return nil
    }
    guard let jsonResponse = jsonDeserialized as? [String: Any] else {
      XCTFail("Unable to decode from json as [String: Any]: \(stdoutput)")
      return nil
    }
    guard let project = jsonResponse["project"] as? [String: Any] else {
      XCTFail("Unable to extract project from \(jsonResponse)")
      return nil
    }
    return project
  }

  /// Returns targets of a project.
  ///
  /// - Parameters:
  ///   - xcodeProjectURL: URL of project.
  /// - Returns
  ///   - Array of target names.
  func targetsOfXcodeProject(_ xcodeProjectURL: URL) -> [String] {
    guard let project = xcodeProjectDictionary(xcodeProjectURL) else {
      XCTFail("Unable to extract project for \(xcodeProjectURL)")
      return []
    }
    guard let targets = project["targets"] as? [String] else {
      XCTFail("Unable to extract targets from \(project)")
      return []
    }
    return targets
  }


  /// Builds an Xcode Target
  ///
  /// - Parameters:
  ///   - xcodeProjectURL: URL of project.
  ///   - target: target name
  func buildXcodeTarget(_ xcodeProjectURL: URL, target: String) {
    let destination = "platform=iOS Simulator,name=\(TulsiEndToEndTest.simulatorName),OS=\(TulsiEndToEndTest.targetVersion)"
    let completionInfo = ProcessRunner.launchProcessSync("/usr/bin/xcodebuild",
                                                         arguments: ["build",
                                                                     "-project",
                                                                     xcodeProjectURL.path,
                                                                     "-target",
                                                                     target,
                                                                     "-destination",
                                                                     destination,
                                                                     "SYMROOT=xcodeBuild"])

    if let stdoutput = String(data: completionInfo.stdout, encoding: .utf8),
        !stdoutput.isEmpty,
        let result = stdoutput.split(separator: "\n").last {
      if (String(result) != "** BUILD SUCCEEDED **") {
        print(stdoutput)
        XCTFail("\(completionInfo.commandlineString) did not return build success. Exit code: \(completionInfo.terminationStatus)")
      }
    } else if let error = String(data: completionInfo.stderr, encoding: .utf8), !error.isEmpty {
      XCTFail(error)
    } else {
      XCTFail("Xcode project build did not return success \(xcodeProjectURL):\(target).")
    }
  }

  // Runs Xcode tests on the given Xcode project and scheme. This verifies that
  // the test passes and that rsync behavior is used to copy files.
  func testXcodeProject(_ xcodeProjectURL: URL, scheme: String) {
    let destination = "platform=iOS Simulator,name=\(TulsiEndToEndTest.simulatorName),OS=\(TulsiEndToEndTest.targetVersion)"
    let completionInfo = ProcessRunner.launchProcessSync("/usr/bin/xcodebuild",
                                                         arguments: ["test",
                                                                     "-project",
                                                                     xcodeProjectURL.path,
                                                                     "-scheme",
                                                                     scheme,
                                                                     "-destination",
                                                                     destination])

    if let stdoutput = String(data: completionInfo.stdout, encoding: .utf8),
        !stdoutput.isEmpty,
        let result = stdoutput.split(separator: "\n").last {
      XCTAssert(stdoutput.contains("Rsyncing"), "Failed to find 'Rsyncing' in:\n\(stdoutput)")
      if (String(result) != "** TEST SUCCEEDED **") {
        print(stdoutput)
        XCTFail("\(completionInfo.commandlineString) did not return test success. Exit code: \(completionInfo.terminationStatus)")
      }
    } else if let error = String(data: completionInfo.stderr, encoding: .utf8), !error.isEmpty {
      XCTFail(error)
    } else {
      XCTFail("Xcode project tests did not return success \(xcodeProjectURL):\(scheme).")
    }
  }

  // Runs 'simctl' in a subprocess with whatever command (i.e. boot, shutdown, delete, etc) and
  // target simulator specified.
  fileprivate func runSimctlCommand(_ command: String, onSimulator target: String) {
    let completionInfo = ProcessRunner.launchProcessSync("/usr/bin/xcrun",
                                              arguments: ["simctl",
                                                          command,
                                                          target])

    if let error = String(data: completionInfo.stderr, encoding: .utf8), !error.isEmpty {
      print("""
            \(completionInfo.commandlineString) failed with exit code: \(completionInfo.terminationStatus)
            Error: \(error)
            """)
    }
  }
}

extension FileManager {
  // Performs a deep copy of the item at sourceURL, resolving any symlinks along the way.
  func deepCopyItem(at sourceURL: URL, to destURL: URL) throws {
    do {
      try self.createDirectory(atPath: destURL.deletingLastPathComponent().path, withIntermediateDirectories: true)
      let rootPath = sourceURL.path
      if let rootAttributes = try? self.attributesOfItem(atPath: rootPath) {
        if rootAttributes[FileAttributeKey.type] as? FileAttributeType == FileAttributeType.typeSymbolicLink {
          let resolvedRootPath = try self.destinationOfSymbolicLink(atPath: rootPath)
          try self.copyItem(atPath: resolvedRootPath, toPath: destURL.path)
        } else {
          try self.copyItem(at: sourceURL, to: destURL)
        }
      }

      let path = destURL.path
      if let paths = self.subpaths(atPath: path) {
        for subpath in paths {
          let fullSubpath = path + "/" + subpath
          if let attributes = try? self.attributesOfItem(atPath: fullSubpath) {
            // If a file is a symbolic link, find the original file, remove the symlink, and copy
            // over the original file.
            if attributes[FileAttributeKey.type] as? FileAttributeType == FileAttributeType.typeSymbolicLink {
              let resolvedPath = try self.destinationOfSymbolicLink(atPath: fullSubpath)
              try self.removeItem(atPath: fullSubpath)
              try self.copyItem(atPath: resolvedPath, toPath: fullSubpath)
            }
          }
        }
      }
    }
  }
}

