// 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")],
      postProcessor: URL(fileURLWithPath: "/utils/covmap_patcher"),
      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"))
    } 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) -> BuildLabel {
      let label = BuildLabel(labelName)
      mockExtractor.labelToRuleEntry[label] = type(of: self).makeRuleEntry(label,
                                                                           type: type,
                                                                           attributes: attributes,
                                                                           weakDependencies: weakDependencies,
                                                                           extensions: extensions,
                                                                           extensionType: extensionType)
      return label
    }

    let test1 = addRule("//test:ExtFoo", type: "ios_extension", extensionType: "com.apple.extension-foo")
    let test2 = addRule("//test:ExtBar", type: "ios_extension", extensionType: "com.apple.extension-bar")
    addRule("//test:Application", type: "ios_application", extensions: [test1, test2])
    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 testTestSuiteSchemeGeneration() {
    checkTestSuiteSchemeGeneration("ios_test", testHostAttributeName: "xctest_app")
  }

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

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

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

    let app = addRule("//test:Application", type: "ios_application")
    let test1 = addRule("//test:TestOne", type: testRuleType, attributes: [testHostAttributeName: app.value as AnyObject])
    let test2 = addRule("//test:TestTwo", type: testRuleType, attributes: [testHostAttributeName: app.value as AnyObject])
    addRule("//test:UnusedTest", type: testRuleType)
    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")
    }
    return ret
  }

  private static func makeRuleEntry(_ label: BuildLabel,
                                    type: String,
                                    attributes: [String: AnyObject] = [:],
                                    artifacts: [BazelFileInfo] = [],
                                    sourceFiles: [BazelFileInfo] = [],
                                    nonARCSourceFiles: [BazelFileInfo] = [],
                                    dependencies: Set<String> = Set(),
                                    secondaryArtifacts: [BazelFileInfo] = [],
                                    weakDependencies: Set<BuildLabel>? = nil,
                                    buildFilePath: String? = nil,
                                    defines: [String]? = nil,
                                    includePaths: [RuleEntry.IncludePath]? = nil,
                                    extensions: Set<BuildLabel>? = 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,
                     platformType: platformType,
                     osDeploymentTarget: osDeploymentTarget,
                     buildFilePath: buildFilePath,
                     defines: defines,
                     includePaths: includePaths,
                     extensionType: extensionType)
  }

  private func prepareGenerator(_ ruleEntries: [BuildLabel: RuleEntry]) {
    config = TulsiGeneratorConfig(projectName: XcodeProjectGeneratorTests.projectName,
                                  buildTargetLabels: Array(ruleEntries.keys),
                                  pathFilters: pathFilters,
                                  additionalFilePaths: additionalFilePaths,
                                  options: TulsiOptionSet(),
                                  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 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 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.writeDataHandler = { (url, _) in
      self.writtenFiles.insert(url.path)
    }
    generator.usernameFetcher = { "USER" }
  }
}


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

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

  override func createDirectory(at url: URL,
                                     withIntermediateDirectories createIntermediates: Bool,
                                     attributes: [String:Any]?) throws {
    if allowedDirectoryCreates.contains(url.path) { return }
    throw NSError(domain: "MockFileManager: Directory creation disallowed",
                  code: 0,
                  userInfo: nil)
  }

  override func createDirectory(atPath path: String,
                                      withIntermediateDirectories createIntermediates: Bool,
                                      attributes: [String:Any]?) throws {
    if allowedDirectoryCreates.contains(path) { return }
    throw NSError(domain: "MockFileManager: Directory creation disallowed",
                  code: 0,
                  userInfo: nil)
  }

  override func removeItem(at URL: URL) throws {
    throw NSError(domain: "MockFileManager: removeItem disallowed", code: 0, userInfo: nil)
  }

  override func removeItem(atPath path: String) throws {
    throw NSError(domain: "MockFileManager: removeItem disallowed", code: 0, userInfo: nil)
  }

  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: [String : Any]? = nil) -> Bool {
    if writeOperations.keys.contains(path) {
      fatalError("Attempting to overwrite an existing file at \(path)")
    }
    writeOperations[path] = data
    return true
  }
}


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(bazelURL: URL,
                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: [BuildLabel:RuleEntry],
                                   pathFilters: Set<String>) {
  }

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

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

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

  func generateBuildTargetsForRuleEntries(_ ruleEntries: Set<RuleEntry>,
                                          ruleEntryMap: [BuildLabel: RuleEntry]) throws -> [String: [String]] {
    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!)

      for attribute in [.xctest_app, .test_host] as [RuleEntry.Attribute] {
        if let hostLabelString = entry.attributes[attribute] 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)
    }

    return [:]
  }
}
