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

/// Models the label and type of a single supported Bazel target.
/// See http://bazel.build/docs/build-ref.html#targets.
public class RuleInfo: Equatable, Hashable, CustomDebugStringConvertible {
  public let label: BuildLabel
  public let type: String
  /// Set of BuildLabels referencing targets that are required by this RuleInfo. For example, test
  /// hosts for XCTest targets.
  public let linkedTargetLabels: Set<BuildLabel>

  public var hashValue: Int {
    return label.hashValue ^ type.hashValue
  }

  public var debugDescription: String {
    return "\(type(of: self))(\(label) \(type))"
  }

  init(label: BuildLabel, type: String, linkedTargetLabels: Set<BuildLabel>) {
    self.label = label
    self.type = type
    self.linkedTargetLabels = linkedTargetLabels
  }
}


/// Encapsulates data about a file that may be a Bazel input or output.
public class BazelFileInfo: Equatable, Hashable, CustomDebugStringConvertible {
  public enum TargetType: Int {
    case sourceFile
    case generatedFile
  }

  /// The path to this file relative to rootPath.
  public let subPath: String

  /// The root of this file's path (typically used to indicate the path to a generated file's root).
  public let rootPath: String

  /// The type of this file.
  public let targetType: TargetType

  /// Whether or not this file object is a directory.
  public let isDirectory: Bool

  public lazy var fullPath: String = { [unowned self] in
    return NSString.path(withComponents: [self.rootPath, self.subPath])
  }()

  public lazy var uti: String? = { [unowned self] in
    return self.subPath.pbPathUTI
  }()

  public lazy var hashValue: Int = { [unowned self] in
    return self.subPath.hashValue &+
        self.rootPath.hashValue &+
        self.targetType.hashValue &+
        self.isDirectory.hashValue
  }()

  init?(info: AnyObject?) {
    guard let info = info as? [String: AnyObject] else {
      return nil
    }

    guard let subPath = info["path"] as? String,
              let isSourceFile = info["src"] as? Bool else {
      assertionFailure("Aspect provided a file info dictionary but was missing required keys")
      return nil
    }

    self.subPath = subPath
    if let rootPath = info["root"] as? String {
      // Patch up
      self.rootPath = rootPath
    } else {
      self.rootPath = ""
    }
    self.targetType = isSourceFile ? .sourceFile : .generatedFile

    self.isDirectory = info["is_dir"] as? Bool ?? false
  }

  init(rootPath: String, subPath: String, isDirectory: Bool, targetType: TargetType) {
    self.rootPath = rootPath
    self.subPath = subPath
    self.isDirectory = isDirectory
    self.targetType = targetType
  }

  // MARK: - CustomDebugStringConvertible
  public lazy var debugDescription: String = { [unowned self] in
    return "{\(self.fullPath) \(self.isDirectory ? "<DIR> " : "")\(self.targetType)}"
  }()
}

public func ==(lhs: BazelFileInfo, rhs: BazelFileInfo) -> Bool {
  return lhs.targetType == rhs.targetType &&
      lhs.rootPath == rhs.rootPath &&
      lhs.subPath == rhs.subPath &&
      lhs.isDirectory == rhs.isDirectory
}


/// Models the full metadata of a single supported Bazel target.
/// See http://bazel.build/docs/build-ref.html#targets.
public final class RuleEntry: RuleInfo {
  // Include paths are represented by a string and a boolean indicating whether they should be
  // searched recursively or not.
  public typealias IncludePath = (String, Bool)

  /// Mapping of BUILD file type to Xcode Target type.
  static let BuildTypeToTargetType = [
      "apple_ui_test": PBXTarget.ProductType.UIUnitTest,
      "apple_unit_test": PBXTarget.ProductType.UnitTest,
      "apple_watch1_extension": PBXTarget.ProductType.Watch1App,
      "apple_watch2_extension": PBXTarget.ProductType.Watch2App,
      "ios_application": PBXTarget.ProductType.Application,
      "ios_extension": PBXTarget.ProductType.AppExtension,
      "ios_framework": PBXTarget.ProductType.Framework,
      "ios_test": PBXTarget.ProductType.UnitTest,
      "objc_binary": PBXTarget.ProductType.Application,
      "objc_library": PBXTarget.ProductType.StaticLibrary,
      "swift_library": PBXTarget.ProductType.StaticLibrary,
      "tvos_application": PBXTarget.ProductType.Application,
      "tvos_extension": PBXTarget.ProductType.TVAppExtension,


      // Support new rules that have underscore-prefixed names because they are wrapped by macros.
      "_ios_application": PBXTarget.ProductType.Application,
      "_ios_extension": PBXTarget.ProductType.AppExtension,
      "_tvos_application": PBXTarget.ProductType.Application,
      "_tvos_extension": PBXTarget.ProductType.TVAppExtension,

      // A Tulsi-internal generic "test host", used to generate build targets that act as hosts for
      // XCTest test rules.
      "_test_host_": PBXTarget.ProductType.Application,
  ]

  /// Keys for a RuleEntry's attributes map. Definitions may be found in the Bazel Build
  /// Encyclopedia (see http://bazel.build/docs/be/overview.html).
  // Note: This set of must be kept in sync with the tulsi_aspects aspect.
  public enum Attribute: String {
    case binary
    case bridging_header
    // Contains defines that were specified by the user on the commandline or are built into
    // Bazel itself.
    case compiler_defines
    case copts
    case datamodels
    case defines
    case enable_modules
    case has_swift_dependency
    case includes
    case launch_storyboard
    case pch
    case swift_language_version
    case swift_toolchain
    // Contains various files that are used as part of the build process but need no special
    // handling in the generated Xcode project. For example, asset_catalog, storyboard, and xibs
    // attributes all end up as supporting_files.
    case supporting_files
    // For the apple_unit_test and apple_ui_test rules, contains a label reference to the
    // ios_application target to be used as the test host when running the tests.
    case test_host
    // For the ios_test rule, specifies whether the test is XCTest based or not (i.e. KIF).
    case xctest
    // For the ios_test rule, contains a label reference to the ios_application target to be used as
    // the test host when running the tests.
    case xctest_app
  }

  /// Bazel attributes for this rule (e.g., "binary": <some label> on an ios_application).
  public let attributes: [Attribute: AnyObject]

  /// Artifacts produced by Bazel when this rule is built.
  public let artifacts: [BazelFileInfo]

  /// Source files associated with this rule.
  public let sourceFiles: [BazelFileInfo]

  /// Non-ARC source files associated with this rule.
  public let nonARCSourceFiles: [BazelFileInfo]

  /// Paths to generated directories that will include header files.
  public let generatedIncludePaths: [IncludePath]?

  /// Set of the labels that this rule depends on.
  public let dependencies: Set<String>

  /// Set of ios_application extension labels that this rule utilizes.
  public let extensions: Set<BuildLabel>

  /// .framework bundles provided by this rule.
  public let frameworkImports: [BazelFileInfo]

  /// List of implicit artifacts that are generated by this rule.
  public let secondaryArtifacts: [BazelFileInfo]

  /// The Swift language version used by this target.
  public let swiftLanguageVersion: String?

  /// The swift toolchain argument used by this target.
  // TODO(abaire): It is hoped that this may be removed when support for Swift 2.3 is dropped.
  public let swiftToolchain: String?

  /// List containing the transitive swiftmodules on which this rule depends.
  public let swiftTransitiveModules: [BazelFileInfo]

  /// List containing the transitive ObjC modulemaps on which this rule depends.
  public let objCModuleMaps: [BazelFileInfo]

  /// The minimum iOS version supported by this target.
  public let iPhoneOSDeploymentTarget: String?

  /// The minimum macOS version supported by this target.
  public let macOSDeploymentTarget: String?

  /// The minimum tvOS version supported by this target.
  public let tvOSDeploymentTarget: String?

  /// The minimum watchOS version supported by this target.
  public let watchOSDeploymentTarget: String?

  /// Set of labels that this rule depends on but does not require.
  // NOTE(abaire): This is a hack used for test_suite rules, where the possible expansions retrieved
  // via queries are filtered by the existence of the selected labels extracted via the normal
  // aspect path. Ideally the aspect would be able to directly express the relationship between the
  // test_suite and the test rules themselves, but that expansion is done prior to the application
  // of the aspect.
  public var weakDependencies = Set<BuildLabel>()

  /// Transitive set of artifacts produced by the dependencies of this RuleEntry. Note that this
  /// must be populated via the discoverIntermediateArtifacts method.
  private(set) public var intermediateArtifacts: Set<BazelFileInfo>? = nil

  /// The BUILD file that this rule was defined in.
  public let buildFilePath: String?

  // The CFBundleIdentifier associated with the target for this rule, if any.
  public let bundleID: String?

  /// The CFBundleIdentifier of the watchOS extension target associated with this rule, if any.
  public let extensionBundleID: String?

  /// The NSExtensionPointIdentifier of the extension associated with this rule, if any.
  public let extensionType: String?

  /// Returns the set of non-versioned artifacts that are not source files.
  public var normalNonSourceArtifacts: [BazelFileInfo] {
    var artifacts = [BazelFileInfo]()
    if let description = attributes[.launch_storyboard] as? [String: AnyObject],
           let fileTarget = BazelFileInfo(info: description as AnyObject?) {
      artifacts.append(fileTarget)
    }

    if let fileTargets = parseFileDescriptionListAttribute(.supporting_files) {
      artifacts.append(contentsOf: fileTargets)
    }

    return artifacts
  }

  /// Returns the set of artifacts for which a versioned group should be created in the generated
  /// Xcode project.
  public var versionedNonSourceArtifacts: [BazelFileInfo] {
    if let fileTargets = parseFileDescriptionListAttribute(.datamodels) {
      return fileTargets
    }
    return []
  }

  /// The full set of input and output artifacts for this rule.
  public var projectArtifacts: [BazelFileInfo] {
    var artifacts = sourceFiles
    artifacts.append(contentsOf: nonARCSourceFiles)
    artifacts.append(contentsOf: frameworkImports)
    artifacts.append(contentsOf: normalNonSourceArtifacts)
    artifacts.append(contentsOf: versionedNonSourceArtifacts)
    return artifacts
  }

  private(set) lazy var pbxTargetType: PBXTarget.ProductType? = { [unowned self] in
    if self.type == "ios_test",
       let xctestOpt = self.attributes[.xctest] as? Bool, !xctestOpt {
      return BuildTypeToTargetType["ios_application"]
    }

    return BuildTypeToTargetType[self.type]
  }()

  /// Returns the value to be used as the Xcode SDKROOT for the build target generated for this
  /// RuleEntry.
  private(set) lazy var XcodeSDKRoot: String? = { [unowned self] in
    guard let targetType = self.pbxTargetType else {
      return nil
    }

    // Watch1App intentionally uses the iphoneos SDK, the watchos SDK was only added by Apple for
    // watchOS2 and later.
    if targetType == .Watch2App {
      return "watchos"
    }

    // tvOS apps and iOS apps both use the same product type, so we have to use
    // the rule name to distinguish them.
    if targetType == .TVAppExtension || self.type == "tvos_application" ||
        self.type == "_tvos_application" {
      return "appletvos"
    }

    return "iphoneos"
  }()

  /// For rule types that generate an implicit name.ipa target, returns a BuildLabel usable to
  /// generate the IPA.
  let implicitIPATarget: BuildLabel?

  init(label: BuildLabel,
       type: String,
       attributes: [String: AnyObject],
       artifacts: [BazelFileInfo] = [],
       sourceFiles: [BazelFileInfo] = [],
       nonARCSourceFiles: [BazelFileInfo] = [],
       dependencies: Set<String> = Set(),
       frameworkImports: [BazelFileInfo] = [],
       secondaryArtifacts: [BazelFileInfo] = [],
       weakDependencies: Set<BuildLabel>? = nil,
       extensions: Set<BuildLabel>? = nil,
       bundleID: String? = nil,
       extensionBundleID: String? = nil,
       iPhoneOSDeploymentTarget: String? = nil,
       macOSDeploymentTarget: String? = nil,
       tvOSDeploymentTarget: String? = nil,
       watchOSDeploymentTarget: String? = nil,
       buildFilePath: String? = nil,
       generatedIncludePaths: [IncludePath]? = nil,
       swiftLanguageVersion: String? = nil,
       swiftToolchain: String? = nil,
       swiftTransitiveModules: [BazelFileInfo] = [],
       objCModuleMaps: [BazelFileInfo] = [],
       implicitIPATarget: BuildLabel? = nil,
       extensionType: String? = nil) {

    var checkedAttributes = [Attribute: AnyObject]()
    for (key, value) in attributes {
      guard let checkedKey = Attribute(rawValue: key) else {
        print("Tulsi rule \(label.value) - Ignoring unknown attribute key \(key)")
        assertionFailure("Unknown attribute key \(key)")
        continue
      }
      checkedAttributes[checkedKey] = value
    }
    self.attributes = checkedAttributes

    self.artifacts = artifacts
    self.sourceFiles = sourceFiles
    self.nonARCSourceFiles = nonARCSourceFiles
    self.dependencies = dependencies
    self.frameworkImports = frameworkImports
    self.secondaryArtifacts = secondaryArtifacts
    if let weakDependencies = weakDependencies {
      self.weakDependencies = weakDependencies
    }
    if let extensions = extensions {
      self.extensions = extensions
    } else {
      self.extensions = Set()
    }
    self.bundleID = bundleID
    self.extensionBundleID = extensionBundleID
    self.iPhoneOSDeploymentTarget = iPhoneOSDeploymentTarget
    self.macOSDeploymentTarget = macOSDeploymentTarget
    self.tvOSDeploymentTarget = tvOSDeploymentTarget
    self.watchOSDeploymentTarget = watchOSDeploymentTarget
    self.buildFilePath = buildFilePath
    self.generatedIncludePaths = generatedIncludePaths
    self.swiftLanguageVersion = swiftLanguageVersion
    self.swiftToolchain = swiftToolchain
    self.swiftTransitiveModules = swiftTransitiveModules
    self.objCModuleMaps = objCModuleMaps
    self.implicitIPATarget = implicitIPATarget
    self.extensionType = extensionType

    var linkedTargetLabels = Set<BuildLabel>()
    for attribute in [.xctest_app, .test_host] as [RuleEntry.Attribute] {
      if let hostLabelString = self.attributes[attribute] as? String {
        linkedTargetLabels.insert(BuildLabel(hostLabelString))
      }
    }

    super.init(label: label, type: type, linkedTargetLabels: linkedTargetLabels)
  }

  convenience init(label: String,
                   type: String,
                   attributes: [String: AnyObject],
                   artifacts: [BazelFileInfo] = [],
                   sourceFiles: [BazelFileInfo] = [],
                   nonARCSourceFiles: [BazelFileInfo] = [],
                   dependencies: Set<String> = Set(),
                   frameworkImports: [BazelFileInfo] = [],
                   secondaryArtifacts: [BazelFileInfo] = [],
                   weakDependencies: Set<BuildLabel>? = nil,
                   extensions: Set<BuildLabel>? = nil,
                   bundleID: String? = nil,
                   extensionBundleID: String? = nil,
                   iPhoneOSDeploymentTarget: String? = nil,
                   macOSDeploymentTarget: String? = nil,
                   tvOSDeploymentTarget: String? = nil,
                   watchOSDeploymentTarget: String? = nil,
                   buildFilePath: String? = nil,
                   generatedIncludePaths: [IncludePath]? = nil,
                   swiftLanguageVersion: String? = nil,
                   swiftToolchain: String? = nil,
                   swiftTransitiveModules: [BazelFileInfo] = [],
                   objCModuleMaps: [BazelFileInfo] = [],
                   implicitIPATarget: BuildLabel? = nil,
                   extensionType: String? = nil) {
    self.init(label: BuildLabel(label),
              type: type,
              attributes: attributes,
              artifacts: artifacts,
              sourceFiles: sourceFiles,
              nonARCSourceFiles: nonARCSourceFiles,
              dependencies: dependencies,
              frameworkImports: frameworkImports,
              secondaryArtifacts: secondaryArtifacts,
              weakDependencies: weakDependencies,
              extensions: extensions,
              bundleID: bundleID,
              extensionBundleID: extensionBundleID,
              iPhoneOSDeploymentTarget: iPhoneOSDeploymentTarget,
              macOSDeploymentTarget: macOSDeploymentTarget,
              tvOSDeploymentTarget: tvOSDeploymentTarget,
              watchOSDeploymentTarget: watchOSDeploymentTarget,
              buildFilePath: buildFilePath,
              generatedIncludePaths: generatedIncludePaths,
              swiftLanguageVersion: swiftLanguageVersion,
              swiftToolchain: swiftToolchain,
              swiftTransitiveModules: swiftTransitiveModules,
              objCModuleMaps: objCModuleMaps,
              implicitIPATarget: implicitIPATarget,
              extensionType: extensionType)
  }

  public func discoverIntermediateArtifacts(_ ruleEntryMap: [BuildLabel: RuleEntry]) -> Set<BazelFileInfo> {
    if intermediateArtifacts != nil { return intermediateArtifacts! }

    var collectedArtifacts = Set<BazelFileInfo>()
    for dep in dependencies {
      guard let dependentEntry = ruleEntryMap[BuildLabel(dep)] else {
        // TODO(abaire): Consider making this a standard Tulsi warning.
        // In theory it shouldn't happen and the unknown dep should be tracked elsewhere.
        print("Tulsi rule '\(label.value)' - Ignoring unknown dependency '\(dep)'")
        continue
      }

      collectedArtifacts.formUnion(dependentEntry.artifacts)
      collectedArtifacts.formUnion(dependentEntry.discoverIntermediateArtifacts(ruleEntryMap))
    }

    intermediateArtifacts = collectedArtifacts
    return intermediateArtifacts!
  }

  // MARK: Private methods

  private func parseFileDescriptionListAttribute(_ attribute: RuleEntry.Attribute) -> [BazelFileInfo]? {
    guard let descriptions = attributes[attribute] as? [[String: AnyObject]] else {
      return nil
    }

    var fileTargets = [BazelFileInfo]()
    for description in descriptions {
      guard let target = BazelFileInfo(info: description as AnyObject?) else {
        assertionFailure("Failed to resolve file description to a file target")
        continue
      }
      fileTargets.append(target)
    }
    return fileTargets
  }
}

// MARK: - Equatable

public func ==(lhs: RuleInfo, rhs: RuleInfo) -> Bool {
  return lhs.type == rhs.type && lhs.label == rhs.label
}
