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


class XcodeProjectGeneratorTests: XCTestCase {
  static let outputFolderPath = "/dev/null/project"
  static let projectName = "ProjectName"

  let outputFolderURL = URL(fileURLWithPath: XcodeProjectGeneratorTests.outputFolderPath)
  let xcodeProjectPath = "\(XcodeProjectGeneratorTests.outputFolderPath)/\(XcodeProjectGeneratorTests.projectName).xcodeproj"

  let workspaceRoot = URL(fileURLWithPath: "/workspace")
  let testTulsiVersion = "9.99.999.9999"

  let buildTargetLabels = ["//test:MainTarget", "//test/path/to/target:target"].map({ BuildLabel($0) })
  let pathFilters = Set<String>(["test", "additional"])

  let additionalFilePaths = ["additional/File1", "additional/File2"]

  let bazelURL = TulsiParameter(value: URL(fileURLWithPath: "/test/dir/testBazel"),
                            source: .explicitlyProvided)

  let resourceURLs = XcodeProjectGenerator.ResourceSourcePathURLs(
      buildScript: URL(fileURLWithPath: "/scripts/Build"),
      cleanScript: URL(fileURLWithPath: "/scripts/Clean"),
      extraBuildScripts: [URL(fileURLWithPath: "/scripts/Logging")],
      iOSUIRunnerEntitlements: URL(fileURLWithPath: "/generatedProjectResources/iOSXCTRunner.entitlements"),
      macOSUIRunnerEntitlements: URL(fileURLWithPath: "/generatedProjectResources/macOSXCTRunner.entitlements"),
      stubInfoPlist: URL(fileURLWithPath: "/generatedProjectResources/StubInfoPlist.plist"),
      stubIOSAppExInfoPlistTemplate: URL(fileURLWithPath: "/generatedProjectResources/stubIOSAppExInfoPlist.plist"),
      stubWatchOS2InfoPlist: URL(fileURLWithPath: "/generatedProjectResources/StubWatchOS2InfoPlist.plist"),
      stubWatchOS2AppExInfoPlist: URL(fileURLWithPath: "/generatedProjectResources/StubWatchOS2AppExInfoPlist.plist"),
      bazelWorkspaceFile: URL(fileURLWithPath: "/WORKSPACE"),
      tulsiPackageFiles: [URL(fileURLWithPath: "/tulsi/tulsi_aspects.bzl")])

  var config: TulsiGeneratorConfig! = nil
  var mockLocalizedMessageLogger: MockLocalizedMessageLogger! = nil
  var mockFileManager: MockFileManager! = nil
  var mockExtractor: MockWorkspaceInfoExtractor! = nil
  var generator: XcodeProjectGenerator! = nil

  var writtenFiles = Set<String>()

  override func setUp() {
    super.setUp()
    mockLocalizedMessageLogger = MockLocalizedMessageLogger()
    mockFileManager = MockFileManager()
    mockExtractor = MockWorkspaceInfoExtractor()
    writtenFiles.removeAll()
  }

  func testSuccessfulGeneration() {
    let ruleEntries = XcodeProjectGeneratorTests.labelToRuleEntryMapForLabels(buildTargetLabels)
    prepareGenerator(ruleEntries)
    do {
      _ = try generator.generateXcodeProjectInFolder(outputFolderURL)
      mockLocalizedMessageLogger.assertNoErrors()
      mockLocalizedMessageLogger.assertNoWarnings()

      XCTAssert(writtenFiles.contains("\(xcodeProjectPath)/project.pbxproj"))
      XCTAssert(writtenFiles.contains("\(xcodeProjectPath)/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings"))
      XCTAssert(writtenFiles.contains("\(xcodeProjectPath)/project.xcworkspace/xcuserdata/USER.xcuserdatad/WorkspaceSettings.xcsettings"))
      XCTAssert(writtenFiles.contains("\(xcodeProjectPath)/xcshareddata/xcschemes/test-path-to-target-target.xcscheme"))
      XCTAssert(writtenFiles.contains("\(xcodeProjectPath)/xcshareddata/xcschemes/test-MainTarget.xcscheme"))

      let supportScriptsURL = mockFileManager.homeDirectoryForCurrentUser.appendingPathComponent(
          "Library/Application Support/Tulsi/Scripts", isDirectory: true)
      XCTAssert(mockFileManager.directoryOperations.contains(supportScriptsURL.path))

      let cacheReaderURL = supportScriptsURL.appendingPathComponent("bazel_cache_reader",
                                                                    isDirectory: false)
      XCTAssert(mockFileManager.copyOperations.keys.contains(cacheReaderURL.path))

      let xcp = "\(xcodeProjectPath)/xcuserdata/USER.xcuserdatad/xcschemes/xcschememanagement.plist"
      XCTAssert(!mockFileManager.attributesMap.isEmpty)
      mockFileManager.attributesMap.forEach { (path, attrs) in
        XCTAssertNotNil(attrs[.modificationDate])
      }
      XCTAssert(mockFileManager.writeOperations.keys.contains(xcp))
    } catch let e {
      XCTFail("Unexpected exception \(e)")
    }
  }

  func testExtensionPlistGeneration() {
    @discardableResult
    func addRule(_ labelName: String,
                 type: String,
                 attributes: [String: AnyObject] = [:],
                 weakDependencies: Set<BuildLabel>? = nil,
                 extensions: Set<BuildLabel>? = nil,
                 extensionType: String? = nil,
                 productType: PBXTarget.ProductType? = nil) -> BuildLabel {
      let label = BuildLabel(labelName)
      mockExtractor.labelToRuleEntry[label] = Swift.type(of: self).makeRuleEntry(label,
                                                                           type: type,
                                                                           attributes: attributes,
                                                                           weakDependencies: weakDependencies,
                                                                           extensions: extensions,
                                                                           productType: productType,
                                                                           extensionType: extensionType)
      return label
    }

    let test1 = addRule("//test:ExtFoo", type: "ios_extension", extensionType: "com.apple.extension-foo", productType: .AppExtension)
    let test2 = addRule("//test:ExtBar", type: "ios_extension", extensionType: "com.apple.extension-bar", productType: .AppExtension)
    addRule("//test:Application", type: "ios_application", extensions: [test1, test2], productType: .Application)
    prepareGenerator(mockExtractor.labelToRuleEntry)

    func assertPlist(withData data: Data, equalTo value: NSDictionary) {
      let content = try! PropertyListSerialization.propertyList(from: data, options: PropertyListSerialization.ReadOptions.mutableContainers, format: nil) as! NSDictionary
      XCTAssertEqual(content, value)
    }

    do {
      _ = try generator.generateXcodeProjectInFolder(outputFolderURL)
      mockLocalizedMessageLogger.assertNoErrors()
      mockLocalizedMessageLogger.assertNoWarnings()

      XCTAssert(mockFileManager.writeOperations.keys.contains("\(xcodeProjectPath)/.tulsi/Resources/Stub_test-ExtFoo.plist"))
      assertPlist(withData: mockFileManager.writeOperations["\(xcodeProjectPath)/.tulsi/Resources/Stub_test-ExtFoo.plist"]!,
                  equalTo: ["NSExtension": ["NSExtensionPointIdentifier": "com.apple.extension-foo"]])

      XCTAssert(mockFileManager.writeOperations.keys.contains("\(xcodeProjectPath)/.tulsi/Resources/Stub_test-ExtBar.plist"))
      assertPlist(withData: mockFileManager.writeOperations["\(xcodeProjectPath)/.tulsi/Resources/Stub_test-ExtBar.plist"]!,
                  equalTo: ["NSExtension": ["NSExtensionPointIdentifier": "com.apple.extension-bar"]])
    } catch let e {
      XCTFail("Unexpected exception \(e)")
    }
  }

  func testUnresolvedLabelsThrows() {
    let ruleEntries = XcodeProjectGeneratorTests.labelToRuleEntryMapForLabels(buildTargetLabels)
    prepareGenerator(ruleEntries)
    mockExtractor.labelToRuleEntry = [:]
    do {
      _ = try generator.generateXcodeProjectInFolder(outputFolderURL)
      XCTFail("Generation succeeded unexpectedly")
    } catch XcodeProjectGenerator.ProjectGeneratorError.labelResolutionFailed(let missingLabels) {
      for label in buildTargetLabels {
        XCTAssert(missingLabels.contains(label), "Expected missing label \(label) not found")
      }
    } catch let e {
      XCTFail("Unexpected exception \(e)")
    }
  }

  func testInvalidPathThrows() {
    let ruleEntries = XcodeProjectGeneratorTests.labelToRuleEntryMapForLabels(buildTargetLabels)
    prepareGenerator(ruleEntries)
    let invalidOutputFolderString = "/dev/null/bazel-build"
    let invalidOutputFolderURL = URL(fileURLWithPath: invalidOutputFolderString)

    do {
      _ = try generator.generateXcodeProjectInFolder(invalidOutputFolderURL)
      XCTFail("Generation succeeded unexpectedly")
    } catch XcodeProjectGenerator.ProjectGeneratorError.invalidXcodeProjectPath(let pathFound,
                                                                                let reason) {
      // Expected failure on path with a /bazel-* directory.
      XCTAssertEqual(pathFound, invalidOutputFolderString)
      XCTAssertEqual(reason, "a Bazel generated temp directory (\"/bazel-\")")
    } catch let e {
      XCTFail("Unexpected exception \(e)")
    }
  }

  func testTestSuiteSchemeGenerationWithSkylarkUnitTest() {
    checkTestSuiteSchemeGeneration("apple_unit_test",
                                   testProductType: .UnitTest,
                                   testHostAttributeName: "test_host")
  }

  func testTestSuiteSchemeGenerationWithSkylarkUITest() {
    checkTestSuiteSchemeGeneration("apple_ui_test",
                                   testProductType: .UIUnitTest,
                                   testHostAttributeName: "test_host")
  }

  func checkTestSuiteSchemeGeneration(_ testRuleType: String,
                                      testProductType: PBXTarget.ProductType,
                                      testHostAttributeName: String) {
    @discardableResult
    func addRule(_ labelName: String,
                 type: String,
                 attributes: [String: AnyObject] = [:],
                 weakDependencies: Set<BuildLabel>? = nil,
                 productType: PBXTarget.ProductType? = nil) -> BuildLabel {
      let label = BuildLabel(labelName)
      mockExtractor.labelToRuleEntry[label] = Swift.type(of: self).makeRuleEntry(label,
                                                                             type: type,
                                                                             attributes: attributes,
                                                                             weakDependencies: weakDependencies,
                                                                             productType: productType)
      return label
    }

    let app = addRule("//test:Application", type: "ios_application", productType: .Application)
    let test1 = addRule("//test:TestOne",
                        type: testRuleType,
                        attributes: [testHostAttributeName: app.value as AnyObject],
                        productType: testProductType)
    let test2 = addRule("//test:TestTwo",
                        type: testRuleType,
                        attributes: [testHostAttributeName: app.value as AnyObject],
                        productType: testProductType)
    addRule("//test:UnusedTest", type: testRuleType, productType: testProductType)
    addRule("//test:TestSuite", type: "test_suite", weakDependencies: Set([test1, test2]))
    prepareGenerator(mockExtractor.labelToRuleEntry)

    do {
      _ = try generator.generateXcodeProjectInFolder(outputFolderURL)
      mockLocalizedMessageLogger.assertNoErrors()
      mockLocalizedMessageLogger.assertNoWarnings()

      XCTAssert(writtenFiles.contains("\(xcodeProjectPath)/project.pbxproj"))
      XCTAssert(writtenFiles.contains("\(xcodeProjectPath)/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings"))
      XCTAssert(writtenFiles.contains("\(xcodeProjectPath)/project.xcworkspace/xcuserdata/USER.xcuserdatad/WorkspaceSettings.xcsettings"))
      XCTAssert(writtenFiles.contains("\(xcodeProjectPath)/xcshareddata/xcschemes/test-Application.xcscheme"))
      XCTAssert(writtenFiles.contains("\(xcodeProjectPath)/xcshareddata/xcschemes/test-TestOne.xcscheme"))
      XCTAssert(writtenFiles.contains("\(xcodeProjectPath)/xcshareddata/xcschemes/test-TestTwo.xcscheme"))
      XCTAssert(writtenFiles.contains("\(xcodeProjectPath)/xcshareddata/xcschemes/test-UnusedTest.xcscheme"))
      XCTAssert(writtenFiles.contains("\(xcodeProjectPath)/xcshareddata/xcschemes/TestSuite_Suite.xcscheme"))
    } catch let e {
      XCTFail("Unexpected exception \(e)")
    }
  }

  func testProjectSDKROOT() {
    func validate(_ types: [(String, String)], _ expectedSDKROOT: String?, line: UInt = #line) {
      let rules = types.map() { tuple in
        // Both the platform and osDeploymentTarget must be set in order to create a valid
        // deploymentTarget for the RuleEntry.
        XcodeProjectGeneratorTests.makeRuleEntry(BuildLabel(tuple.0), type: tuple.0, platformType: tuple.1,
                                                 osDeploymentTarget: "this_must_not_be_nil")
      }
      let sdkroot = XcodeProjectGenerator.projectSDKROOT(rules)
      XCTAssertEqual(sdkroot, expectedSDKROOT, line: line)
    }

    let iosAppTuple = ("ios_application", "ios")
    let tvExtensionTuple = ("tvos_extension", "tvos")
    validate([iosAppTuple], "iphoneos")
    validate([iosAppTuple, iosAppTuple], "iphoneos")
    validate([iosAppTuple, tvExtensionTuple], nil)
    validate([tvExtensionTuple], "appletvos")
  }

  // MARK: - Private methods

  private static func labelToRuleEntryMapForLabels(_ labels: [BuildLabel]) -> [BuildLabel: RuleEntry] {
    var ret = [BuildLabel: RuleEntry]()
    for label in labels {
      ret[label] = makeRuleEntry(label, type: "ios_application", productType: .Application)
    }
    return ret
  }

  private static func makeRuleEntry(_ label: BuildLabel,
                                    type: String,
                                    attributes: [String: AnyObject] = [:],
                                    artifacts: [BazelFileInfo] = [],
                                    sourceFiles: [BazelFileInfo] = [],
                                    nonARCSourceFiles: [BazelFileInfo] = [],
                                    dependencies: Set<BuildLabel> = Set(),
                                    secondaryArtifacts: [BazelFileInfo] = [],
                                    weakDependencies: Set<BuildLabel>? = nil,
                                    buildFilePath: String? = nil,
                                    objcDefines: [String]? = nil,
                                    swiftDefines: [String]? = nil,
                                    includePaths: [RuleEntry.IncludePath]? = nil,
                                    extensions: Set<BuildLabel>? = nil,
                                    productType: PBXTarget.ProductType? = nil,
                                    extensionType: String? = nil,
                                    platformType: String? = nil,
                                    osDeploymentTarget: String? = nil) -> RuleEntry {
    return RuleEntry(label: label,
                     type: type,
                     attributes: attributes,
                     artifacts: artifacts,
                     sourceFiles: sourceFiles,
                     nonARCSourceFiles: nonARCSourceFiles,
                     dependencies: dependencies,
                     secondaryArtifacts: secondaryArtifacts,
                     weakDependencies: weakDependencies,
                     extensions: extensions,
                     productType: productType,
                     platformType: platformType,
                     osDeploymentTarget: osDeploymentTarget,
                     buildFilePath: buildFilePath,
                     objcDefines: objcDefines,
                     swiftDefines: swiftDefines,
                     includePaths: includePaths,
                     extensionType: extensionType)
  }

  private func prepareGenerator(_ ruleEntries: [BuildLabel: RuleEntry]) {
    let options = TulsiOptionSet()
    // To avoid creating ~/Library folders and changing UserDefaults during CI testing.
    config = TulsiGeneratorConfig(projectName: XcodeProjectGeneratorTests.projectName,
                                  buildTargetLabels: Array(ruleEntries.keys),
                                  pathFilters: pathFilters,
                                  additionalFilePaths: additionalFilePaths,
                                  options: options,
                                  bazelURL: bazelURL)
    let projectURL = URL(fileURLWithPath: xcodeProjectPath, isDirectory: true)
    mockFileManager.allowedDirectoryCreates.insert(projectURL.path)

    let tulsiworkspace = projectURL.appendingPathComponent("tulsi-workspace")
    mockFileManager.allowedDirectoryCreates.insert(tulsiworkspace.path)

    let bazelCacheReaderURL = mockFileManager.homeDirectoryForCurrentUser.appendingPathComponent(
        "Library/Application Support/Tulsi/Scripts", isDirectory: true)
    mockFileManager.allowedDirectoryCreates.insert(bazelCacheReaderURL.path)

    let xcshareddata = projectURL.appendingPathComponent("project.xcworkspace/xcshareddata")
    mockFileManager.allowedDirectoryCreates.insert(xcshareddata.path)

    let xcuserdata = projectURL.appendingPathComponent("project.xcworkspace/xcuserdata/USER.xcuserdatad")
    mockFileManager.allowedDirectoryCreates.insert(xcuserdata.path)

    let xcschemes = projectURL.appendingPathComponent("xcshareddata/xcschemes")
    mockFileManager.allowedDirectoryCreates.insert(xcschemes.path)

    let userXcschemes = projectURL.appendingPathComponent("xcuserdata/USER.xcuserdatad/xcschemes")
    mockFileManager.allowedDirectoryCreates.insert(userXcschemes.path)

    let scripts = projectURL.appendingPathComponent(".tulsi/Scripts")
    mockFileManager.allowedDirectoryCreates.insert(scripts.path)

    let utils = projectURL.appendingPathComponent(".tulsi/Utils")
    mockFileManager.allowedDirectoryCreates.insert(utils.path)

    let resources = projectURL.appendingPathComponent(".tulsi/Resources")
    mockFileManager.allowedDirectoryCreates.insert(resources.path)

    let tulsiBazelRoot = projectURL.appendingPathComponent(".tulsi/Bazel")
    mockFileManager.allowedDirectoryCreates.insert(tulsiBazelRoot.path)

    let tulsiBazelPackage = projectURL.appendingPathComponent(".tulsi/Bazel/tulsi")
    mockFileManager.allowedDirectoryCreates.insert(tulsiBazelPackage.path)

    let mockTemplate = ["NSExtension": ["NSExtensionPointIdentifier": "com.apple.intents-service"]]
    let templateData = try! PropertyListSerialization.data(fromPropertyList: mockTemplate, format: .xml, options: 0)
    mockFileManager.mockContent[resourceURLs.stubIOSAppExInfoPlistTemplate.path] = templateData

    mockExtractor.labelToRuleEntry = ruleEntries

    generator = XcodeProjectGenerator(workspaceRootURL: workspaceRoot,
                                      config: config,
                                      localizedMessageLogger: mockLocalizedMessageLogger,
                                      workspaceInfoExtractor: mockExtractor,
                                      resourceURLs: resourceURLs,
                                      tulsiVersion: testTulsiVersion,
                                      fileManager: mockFileManager,
                                      pbxTargetGeneratorType: MockPBXTargetGenerator.self)
    generator.redactWorkspaceSymlink = true
    generator.suppressModifyingUserDefaults = true
    generator.suppressGeneratingBuildSettings = true
    generator.writeDataHandler = { (url, _) in
      self.writtenFiles.insert(url.path)
    }
    generator.usernameFetcher = { "USER" }
  }
}


class MockFileManager: FileManager {
  var filesThatExist = Set<String>()
  var allowedDirectoryCreates = Set<String>()
  var directoryOperations = [String]()
  var copyOperations = [String: String]()
  var writeOperations = [String: Data]()
  var removeOperations = [String]()
  var mockContent = [String: Data]()
  var attributesMap = [String: [FileAttributeKey: Any]]()

  override open var homeDirectoryForCurrentUser: URL {
    return URL(fileURLWithPath: "/Users/__MOCK_USER__", isDirectory: true)
  }

  override func fileExists(atPath path: String) -> Bool {
    return filesThatExist.contains(path)
  }

  override func createDirectory(at url: URL,
                                withIntermediateDirectories createIntermediates: Bool,
                                attributes: [FileAttributeKey: Any]?) throws {
    guard !allowedDirectoryCreates.contains(url.path) else {
      directoryOperations.append(url.path)
      if let attributes = attributes {
        self.setAttributes(attributes, path: url.path)
      }
      return
    }
    throw NSError(domain: "MockFileManager: Directory creation disallowed",
                  code: 0,
                  userInfo: nil)
  }

  override func createDirectory(atPath path: String,
                                withIntermediateDirectories createIntermediates: Bool,
                                attributes: [FileAttributeKey: Any]?) throws {
    guard !allowedDirectoryCreates.contains(path) else {
      directoryOperations.append(path)
      if let attributes = attributes {
        self.setAttributes(attributes, path: path)
      }
      return
    }
    throw NSError(domain: "MockFileManager: Directory creation disallowed",
                  code: 0,
                  userInfo: nil)
  }

  override func removeItem(at URL: URL) throws {
    removeOperations.append(URL.path)
  }

  override func removeItem(atPath path: String) throws {
    removeOperations.append(path)
  }

  override func copyItem(at srcURL: URL, to dstURL: URL) throws {
    copyOperations[dstURL.path] = srcURL.path
  }

  override func copyItem(atPath srcPath: String, toPath dstPath: String) throws {
    copyOperations[dstPath] = srcPath
  }

  override func contents(atPath path: String) -> Data? {
    return mockContent[path]
  }

  override func createFile(atPath path: String, contents data: Data?, attributes attr: [FileAttributeKey : Any]? = nil) -> Bool {
    if writeOperations.keys.contains(path) {
      fatalError("Attempting to overwrite an existing file at \(path)")
    }
    writeOperations[path] = data
    if let attr = attr {
      self.setAttributes(attr, path: path)
    }
    return true
  }

  fileprivate func setAttributes(_ attributes: [FileAttributeKey : Any], path: String) {
    var currentAttributes = attributesMap[path] ?? [FileAttributeKey : Any]()
    attributes.forEach { (k, v) in
      currentAttributes[k] = v
    }
    attributesMap[path] = currentAttributes
  }

  override func setAttributes(_ attributes: [FileAttributeKey : Any], ofItemAtPath path: String) throws {
    self.setAttributes(attributes, path: path)
  }
}


final class MockPBXTargetGenerator: PBXTargetGeneratorProtocol {
  var project: PBXProject

  static func getRunTestTargetBuildConfigPrefix() -> String {
    return "TestRunner__"
  }

  static func workingDirectoryForPBXGroup(_ group: PBXGroup) -> String {
    return ""
  }

  static func mainGroupForOutputFolder(_ outputFolderURL: URL, workspaceRootURL: URL) -> PBXGroup {
    return PBXGroup(name: "mainGroup",
                    path: "/A/Test/Path",
                    sourceTree: .Absolute,
                    parent: nil)
  }

  required init(bazelPath: String,
                bazelBinPath: String,
                project: PBXProject,
                buildScriptPath: String,
                stubInfoPlistPaths: StubInfoPlistPaths,
                tulsiVersion: String,
                options: TulsiOptionSet,
                localizedMessageLogger: LocalizedMessageLogger,
                workspaceRootURL: URL,
                suppressCompilerDefines: Bool,
                redactWorkspaceSymlink: Bool) {
    self.project = project
  }

  func generateFileReferencesForFilePaths(_ paths: [String], pathFilters: Set<String>?) {
  }

  func registerRuleEntryForIndexer(_ ruleEntry: RuleEntry,
                                   ruleEntryMap: RuleEntryMap,
                                   pathFilters: Set<String>,
                                   processedEntries: inout [RuleEntry: (NSOrderedSet)]) {
  }

  func generateIndexerTargets() -> [String: PBXTarget] {
    return [:]
  }

  func generateBazelCleanTarget(_ scriptPath: String, workingDirectory: String) {
  }

  func generateTopLevelBuildConfigurations(_ buildSettingOverrides: [String: String]) {
  }

  func generateBuildTargetsForRuleEntries(_ ruleEntries: Set<RuleEntry>,
                                          ruleEntryMap: RuleEntryMap) throws {
    // This works as this file only tests native targets that don't have multiple configurations.
    let namedRuleEntries = ruleEntries.map() { (e: RuleEntry) -> (String, RuleEntry) in
      return (e.label.asFullPBXTargetName!, e)
    }

    var testTargetLinkages = [(PBXTarget, BuildLabel)]()
    for (name, entry) in namedRuleEntries {
      let target = project.createNativeTarget(name,
                                              deploymentTarget: entry.deploymentTarget,
                                              targetType: entry.pbxTargetType!)

      if let hostLabelString = entry.attributes[.test_host] as? String {
        let hostLabel = BuildLabel(hostLabelString)
        testTargetLinkages.append((target, hostLabel))
      }
    }

    for (testTarget, testHostLabel) in testTargetLinkages {
      let hostTarget = project.targetByName(testHostLabel.asFullPBXTargetName!) as! PBXNativeTarget
      project.linkTestTarget(testTarget, toHostTarget: hostTarget)
    }
  }
}
