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


// Concrete extractor that utilizes Bazel query (http://bazel.build/docs/query.html) and aspects to
// extract information from a workspace.
final class BazelWorkspaceInfoExtractor: BazelWorkspaceInfoExtractorProtocol {
  var bazelURL: URL {
    get { return queryExtractor.bazelURL as URL }
    set {
      queryExtractor.bazelURL = newValue
      aspectExtractor.bazelURL = newValue
    }
  }

  /// Returns the workspace relative path to the bazel bin symlink. Note that this may block.
  var bazelBinPath: String {
    return workspacePathInfoFetcher.getBazelBinPath()
  }

  /// Returns the absolute path to the execution root of this Bazel workspace. This may block.
  var bazelExecutionRoot: String {
    return workspacePathInfoFetcher.getExecutionRoot()
  }

  /// Bazel settings provider for all invocations.
  let bazelSettingsProvider: BazelSettingsProviderProtocol

  /// Bazel workspace root URL.
  let workspaceRootURL: URL

  /// Fetcher object from which a workspace's path info may be obtained.
  private let workspacePathInfoFetcher: BazelWorkspacePathInfoFetcher

  private let aspectExtractor: BazelAspectInfoExtractor
  private let queryExtractor: BazelQueryInfoExtractor

  // Cache of all RuleEntry instances loaded for the associated project.
  private var ruleEntryCache = RuleEntryMap()

  init(
    bazelURL: URL,
    workspaceRootURL: URL,
    localizedMessageLogger: LocalizedMessageLogger,
    runAspectsFromWorkspace: Bool
  ) {
    let universalFlags: BazelFlags
      if runAspectsFromWorkspace {
        // No need for any additional flags.
        universalFlags = BazelFlags()
      } else if let applicationSupport = ApplicationSupport() {
        // Install to ~/Library/Application Support when not running inside a test.
        let tulsiVersion = Bundle.main.infoDictionary?["CFBundleVersion"] as? String ?? "UNKNOWN"
        let aspectPath = try! applicationSupport.copyTulsiAspectFiles(tulsiVersion: tulsiVersion)
        universalFlags = BazelFlags(
          // TODO(tulsi-team): See if we can avoid using --override_repository.
          build: ["--override_repository=tulsi=\(aspectPath)"]
        )
      } else {  // Running inside a test, just refer to the files directly from TulsiGenerator.
        let bundle = Bundle(for: type(of: self))
        let bazelWorkspace =
          bundle.url(forResource: "WORKSPACE", withExtension: nil)!.deletingLastPathComponent()
        universalFlags = BazelFlags(build: ["--override_repository=tulsi=\(bazelWorkspace.path)"])
    }

    bazelSettingsProvider = BazelSettingsProvider(universalFlags: universalFlags)
    workspacePathInfoFetcher = BazelWorkspacePathInfoFetcher(bazelURL: bazelURL,
                                                             workspaceRootURL: workspaceRootURL,
                                                             bazelUniversalFlags: universalFlags,
                                                             localizedMessageLogger: localizedMessageLogger)

    let executionRootURL =  URL(fileURLWithPath: workspacePathInfoFetcher.getExecutionRoot(),
                                isDirectory: false)
    aspectExtractor = BazelAspectInfoExtractor(bazelURL: bazelURL,
                                               workspaceRootURL: workspaceRootURL,
                                               executionRootURL: executionRootURL,
                                               bazelSettingsProvider: bazelSettingsProvider,
                                               localizedMessageLogger: localizedMessageLogger)
    queryExtractor = BazelQueryInfoExtractor(bazelURL: bazelURL,
                                             workspaceRootURL: workspaceRootURL,
                                             bazelUniversalFlags: universalFlags,
                                             localizedMessageLogger: localizedMessageLogger)
    self.workspaceRootURL = workspaceRootURL
  }

  // MARK: - BazelWorkspaceInfoExtractorProtocol

  func extractRuleInfoFromProject(_ project: TulsiProject) -> [RuleInfo] {
    return queryExtractor.extractTargetRulesFromPackages(project.bazelPackages)
  }

  func ruleEntriesForLabels(_ labels: [BuildLabel],
                            options: TulsiOptionSet,
                            features: Set<BazelSettingFeature>) throws -> RuleEntryMap {
    func isLabelMissing(_ label: BuildLabel) -> Bool {
      return !ruleEntryCache.hasAnyRuleEntry(withBuildLabel: label)
    }
    let missingLabels = labels.filter(isLabelMissing)
    if missingLabels.isEmpty { return ruleEntryCache }

    let commandLineSplitter = CommandLineSplitter()
    func splitOptionString(_ options: String?) -> [String] {
      guard let options = options else { return [] }
      return commandLineSplitter.splitCommandLine(options) ?? []
    }

    let startupOptions = splitOptionString(options[.BazelBuildStartupOptionsDebug].commonValue) + splitOptionString(options[.ProjectGenerationBazelStartupOptions].commonValue)
    let buildOptions = splitOptionString(options[.BazelBuildOptionsDebug].commonValue)
    let compilationMode = options[.ProjectGenerationCompilationMode].commonValue
    let platformConfig = options[.ProjectGenerationPlatformConfiguration].commonValue
    let prioritizeSwift = options[.ProjectPrioritizesSwift].commonValueAsBool

    if let use64BitWatchSimulatorOption = options[.Use64BitWatchSimulator].commonValueAsBool {
      PlatformConfiguration.use64BitWatchSimulator = use64BitWatchSimulatorOption
    }

    do {
      let ruleEntryMap =
        try aspectExtractor.extractRuleEntriesForLabels(labels,
                                                        aspectBzlLabel: options.aspectsBzlLabel,
                                                        startupOptions: startupOptions,
                                                        buildOptions: buildOptions,
                                                        compilationMode: compilationMode,
                                                        platformConfig: platformConfig,
                                                        prioritizeSwift: prioritizeSwift,
                                                        features: features)
      ruleEntryCache = RuleEntryMap(ruleEntryMap)
    } catch BazelAspectInfoExtractor.ExtractorError.buildFailed {
      throw BazelWorkspaceInfoExtractorError.aspectExtractorFailed("Bazel aspects could not be built.")
    }

    return ruleEntryCache
  }

  func extractBuildfiles<T: Collection>(_ forTargets: T) -> Set<BuildLabel> where T.Iterator.Element == BuildLabel {
    return queryExtractor.extractBuildfiles(forTargets)
  }

  func logQueuedInfoMessages() {
    queryExtractor.logQueuedInfoMessages()
    aspectExtractor.logQueuedInfoMessages()
  }

  func hasQueuedInfoMessages() -> Bool {
    return aspectExtractor.hasQueuedInfoMessages || queryExtractor.hasQueuedInfoMessages
  }
}
