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


/// Keys for all user modifiable Tulsi options.
// Style note: Entries that map directly to Xcode Build Settings values are all caps (matching
// Xcode's use) while entries handled in Tulsi are camel case.
public enum TulsiOptionKey: String {
  case
      // Whether or not to search user header paths first when resolving angle bracket includes.
      ALWAYS_SEARCH_USER_PATHS,

      // What C++ language standard to use for the project.
      CLANG_CXX_LANGUAGE_STANDARD,

      // The path to the Bazel binary.
      BazelPath,
      // Whether or not to claim Swift code was created at the same version as Tulsi itself.
      // Suppresses the Xcode warning and automated update on first opening of the generated
      // project.
      SuppressSwiftUpdateCheck,
      // Whether or not containing a Swift dependency forces dSYM generation (used for debugging).
      SwiftForcesdSYMs,
      // Whether or not to use tree artifact outputs. Should only be disabled if it causes errors.
      // Known issues:
      // - Bundles with spaces in the name
      TreeArtifactOutputs,
      // The path from a config file to its associated workspace root.
      WorkspaceRootPath,

      // Commandline Arguments used by the run phase of the generated scheme.
      CommandlineArguments,

      // Environment Variables used by the run phase of the generated scheme.
      EnvironmentVariables,

      // Option to enable compilation after error.
      BazelContinueBuildingAfterError,

      // Include all .bzl files related to the build in the generated Xcodeproj.
      IncludeBuildSources,

      // Compilation mode to use during project generation.
      ProjectGenerationCompilationMode,

      // Platform configuration to use during project generation.
      ProjectGenerationPlatformConfiguration,

      // Startup options for project generation.
      ProjectGenerationBazelStartupOptions,

      // Improve auto-completion for include/import statements.
      ImprovedImportAutocompletionFix,

      // Generate .runfiles directory, as referenced by TEST_SRCDIR in bazel tests.
      GenerateRunfiles,

      // Used by Tulsi to improve Bazel-caching of build flags.
      ProjectPrioritizesSwift,

      // Custom build phase run script that runs before bazel build.
      PreBuildPhaseRunScript,

      // Custom build phase run script that runs after bazel build.
      PostBuildPhaseRunScript

  // Options for build invocations.
  case BazelBuildOptionsDebug,
       BazelBuildOptionsRelease

  // Startup options for build invocations.
  case BazelBuildStartupOptionsDebug,
       BazelBuildStartupOptionsRelease

  // Pre action scripts for build, launch, and test actions.
  case BuildActionPreActionScript,
       LaunchActionPreActionScript,
       TestActionPreActionScript

  // Post action scripts for build, launch, and test actions.
  case BuildActionPostActionScript,
       LaunchActionPostActionScript,
       TestActionPostActionScript
}


/// Logical groupings for TulsiOptionKeys.
public enum TulsiOptionKeyGroup: String {
  case BazelBuildOptions,
       BazelBuildStartupOptions,
       PreActionScriptOptions,
       PostActionScriptOptions
}


/// Models the set of all user-modifiable options supported by Tulsi.
public class TulsiOptionSet: Equatable {
  /// Suffix added to string keys in order to resolve an option's description.
  static let DescriptionStringKeySuffix = "_DESC"

  /// The key under which option sets are serialized.
  static let PersistenceKey = "optionSet"

  typealias PersistenceType = [String: TulsiOption.PersistenceType]

  static let OptionKeyGroups: [TulsiOptionKey: TulsiOptionKeyGroup] = [
      .ProjectGenerationBazelStartupOptions: .BazelBuildStartupOptions,
      .BazelBuildOptionsDebug: .BazelBuildOptions,
      .BazelBuildOptionsRelease: .BazelBuildOptions,
      .BazelBuildStartupOptionsDebug: .BazelBuildStartupOptions,
      .BazelBuildStartupOptionsRelease: .BazelBuildStartupOptions,
      .BuildActionPreActionScript: .PreActionScriptOptions,
      .LaunchActionPreActionScript: .PreActionScriptOptions,
      .TestActionPreActionScript: .PreActionScriptOptions,
      .BuildActionPostActionScript: .PostActionScriptOptions,
      .LaunchActionPostActionScript: .PostActionScriptOptions,
      .TestActionPostActionScript: .PostActionScriptOptions
  ]

  public var allVisibleOptions = [TulsiOptionKey: TulsiOption]()
  var options = [TulsiOptionKey: TulsiOption]() {
    didSet {
      allVisibleOptions = [TulsiOptionKey: TulsiOption]()
      for (key, option) in options {
        if !option.optionType.contains(.Hidden) {
          allVisibleOptions[key] = option
        }
      }
    }
  }
  var optionKeyGroupInfo = [TulsiOptionKeyGroup: (displayName: String, description: String)]()

  public subscript(optionKey: TulsiOptionKey) -> TulsiOption {
    return options[optionKey]!
  }

  public subscript(optionKey: TulsiOptionKey, target: String) -> String? {
    return options[optionKey]?.valueForTarget(target)
  }

  static func getOptionsFromContainerDictionary(_ dict: [String: Any]) -> PersistenceType? {
    return dict[TulsiOptionSet.PersistenceKey] as? PersistenceType
  }

  public init(withInheritanceEnabled inherit: Bool = false) {
    let bundle = Bundle(for: type(of: self))
    populateOptionsWithBundle(bundle, withInheritAsDefault: inherit)
    populateOptionGroupInfoWithBundle(bundle)
  }

  public convenience init(fromDictionary dict: [String: Any]) {
    self.init()

    guard let persistedOptions = dict as? PersistenceType else {
      assertionFailure("Options dictionary is not of the expected type")
      return
    }

    for (key, option) in options {
      if let value = persistedOptions[key.rawValue] {
        option.deserialize(value)
      }
    }
  }

  /// Returns a new TulsiOptionSet by using the given parent as a base and applying this option
  /// set's options as overrides.
  public func optionSetByInheritingFrom(_ parent: TulsiOptionSet) -> TulsiOptionSet {
    var resolvedOptions = [TulsiOptionKey: TulsiOption]()
    for (key, opt) in options {
      guard let parentOption = parent.options[key] else {
        resolvedOptions[key] = opt
        continue
      }
      resolvedOptions[key] = TulsiOption(resolvingValuesFrom: opt, byInheritingFrom: parentOption)
    }

    let resolvedSet = TulsiOptionSet()
    resolvedSet.options = resolvedOptions
    return resolvedSet
  }

  func saveShareableOptionsIntoDictionary(_ dict: inout [String: Any]) {
    let serialized = saveToDictionary() {
      !$1.optionType.contains(.PerUserOnly)
    }
    dict[TulsiOptionSet.PersistenceKey] = serialized
  }

  func savePerUserOptionsIntoDictionary(_ dict: inout [String: Any]) {
    let serialized = saveToDictionary() {
      return $1.optionType.contains(.PerUserOnly)
    }
    dict[TulsiOptionSet.PersistenceKey] = serialized
  }

  func saveAllOptionsIntoDictionary(_ dict: inout [String: AnyObject]) {
    let serialized = saveToDictionary() { (_, _) in return true }
    dict[TulsiOptionSet.PersistenceKey] = serialized as AnyObject?
  }

  public func groupInfoForOptionKey(_ key: TulsiOptionKey) -> (TulsiOptionKeyGroup, displayName: String, description: String)? {
    guard let keyGroup = TulsiOptionSet.OptionKeyGroups[key] else { return nil }
    guard let (displayName, description) = optionKeyGroupInfo[keyGroup] else {
      assertionFailure("Missing group information for group key \(keyGroup)")
      return (keyGroup, "\(keyGroup)", "")
    }
    return (keyGroup, displayName, description)
  }

  /// Returns a dictionary of build settings without applying any specializations.
  func commonBuildSettings() -> [String: String] {
    // These values come from AppleToolchain.java in Bazel
    // https://github.com/bazelbuild/bazel/blob/master/src/main/java/com/google/devtools/build/lib/rules/apple/AppleToolchain.java
    var buildSettings = [
        "GCC_WARN_64_TO_32_BIT_CONVERSION": "YES",
        "CLANG_WARN_BOOL_CONVERSION": "YES",
        "CLANG_WARN_CONSTANT_CONVERSION": "YES",
        "CLANG_WARN__DUPLICATE_METHOD_MATCH": "YES",
        "CLANG_WARN_EMPTY_BODY": "YES",
        "CLANG_WARN_ENUM_CONVERSION": "YES",
        "CLANG_WARN_INT_CONVERSION": "YES",
        "CLANG_WARN_UNREACHABLE_CODE": "YES",
        "GCC_WARN_ABOUT_RETURN_TYPE": "YES",
        "GCC_WARN_UNDECLARED_SELECTOR": "YES",
        "GCC_WARN_UNINITIALIZED_AUTOS": "YES",
        "GCC_WARN_UNUSED_FUNCTION": "YES",
        "GCC_WARN_UNUSED_VARIABLE": "YES",
    ]

    for (key, opt) in options.filter({ $1.optionType.contains(.BuildSetting) }) {
      buildSettings[key.rawValue] = opt.commonValue!
    }
    return buildSettings
  }

  /// Returns a dictionary of build settings specialized for the given target without inheriting any
  /// defaults.
  func buildSettingsForTarget(_ target: String) -> [String: String] {
    var buildSettings = [String: String]()
    for (key, opt) in options.filter({ $1.optionType.contains(.TargetSpecializableBuildSetting) }) {
      if let val = opt.valueForTarget(target, inherit: false) {
        buildSettings[key.rawValue] = val
      }
    }
    return buildSettings
  }

  // MARK: - Private methods.

  private func saveToDictionary(_ filter: (TulsiOptionKey, TulsiOption) -> Bool) -> PersistenceType {
    var serialized = PersistenceType()
    for (key, option) in options.filter(filter) {
      if let value = option.serialize() {
        serialized[key.rawValue] = value
      }
    }
    return serialized
  }

  private func populateOptionsWithBundle(_ bundle: Bundle, withInheritAsDefault inherit: Bool) {
    func addOption(_ optionKey: TulsiOptionKey, valueType: TulsiOption.ValueType, optionType: TulsiOption.OptionType, defaultValue: String?) {
      let key = optionKey.rawValue
      let displayName = bundle.localizedString(forKey: key, value: nil, table: "Options")
      let descriptionKey = key + TulsiOptionSet.DescriptionStringKeySuffix
      var description = bundle.localizedString(forKey: descriptionKey, value: nil, table: "Options")
      if description == descriptionKey { description = "" }

      let opt = TulsiOption(displayName: displayName,
                            userDescription: description,
                            valueType: valueType,
                            optionType: optionType,
                            defaultValue: defaultValue)
      if inherit && optionType.contains(.SupportsInheritKeyword) {
        opt.projectValue = TulsiOption.InheritKeyword
      }
      options[optionKey] = opt
    }

    func addBoolOption(_ optionKey: TulsiOptionKey, _ optionType: TulsiOption.OptionType, _ defaultValue: Bool = false) {
      let val = defaultValue ? TulsiOption.BooleanTrueValue : TulsiOption.BooleanFalseValue
      addOption(optionKey, valueType: .bool, optionType: optionType, defaultValue: val)
    }

    func addStringOption(_ optionKey: TulsiOptionKey, _ optionType: TulsiOption.OptionType, _ defaultValue: String? = nil) {
      addOption(optionKey, valueType: .string, optionType: optionType, defaultValue: defaultValue)
    }

    func addStringEnumOption(_ optionKey: TulsiOptionKey,
                             _ optionType: TulsiOption.OptionType,
                             _ defaultValue: String,
                             _ values: [String]) {
      assert(values.contains(defaultValue), "Invalid enum for \(optionKey.rawValue): " +
          "defaultValue of \"\(defaultValue)\" is not present in enum values: \(values).")
      addOption(optionKey, valueType: .stringEnum(Set(values)),
                optionType: optionType, defaultValue: defaultValue)
    }

    addBoolOption(.ALWAYS_SEARCH_USER_PATHS, .BuildSetting, false)
    addBoolOption(.BazelContinueBuildingAfterError, .Generic, false)
    addStringOption(.BazelBuildOptionsDebug, [.TargetSpecializable, .SupportsInheritKeyword])
    addStringOption(.BazelBuildOptionsRelease, [.TargetSpecializable, .SupportsInheritKeyword])
    addStringOption(.BazelBuildStartupOptionsDebug, [.TargetSpecializable, .SupportsInheritKeyword])
    addStringOption(.BazelBuildStartupOptionsRelease, [.TargetSpecializable, .SupportsInheritKeyword])
    addBoolOption(.SuppressSwiftUpdateCheck, .Generic, true)
    addBoolOption(.IncludeBuildSources, .Generic, false)
    addBoolOption(.ImprovedImportAutocompletionFix, .Generic, true)
    addBoolOption(.GenerateRunfiles, .Generic, false)
    addBoolOption(.ProjectPrioritizesSwift, .Generic, false)
    addBoolOption(.SwiftForcesdSYMs, .Generic, false)
    addBoolOption(.TreeArtifactOutputs, .Generic, true)

    let defaultIdentifier = PlatformConfiguration.defaultConfiguration.identifier
    let platformCPUIdentifiers = PlatformConfiguration.allValidConfigurations.map { $0.identifier }
    addStringEnumOption(.ProjectGenerationPlatformConfiguration, .Generic,
                        defaultIdentifier, platformCPUIdentifiers)
    addStringEnumOption(.ProjectGenerationCompilationMode, .Generic, "dbg", ["dbg", "opt"])
    addStringOption(.ProjectGenerationBazelStartupOptions, [.SupportsInheritKeyword])

    addStringOption(.CommandlineArguments, [.TargetSpecializable, .SupportsInheritKeyword])
    addStringOption(.EnvironmentVariables, [.TargetSpecializable, .SupportsInheritKeyword])

    // List matches the available options for the 'C++ Language Dialect' setting in XCode 10.2.1 and 11.
    // Currently compiler default is equivalent to GNU++98 (Xcode 10.2.1 and 11)
    let cppLanguageStandards = ["compiler-default", "c++98", "gnu++98", "c++11", "gnu++11", "c++14", "gnu++14", "c++17", "gnu++17"]
    addStringEnumOption(.CLANG_CXX_LANGUAGE_STANDARD, .BuildSetting, "gnu++17",  cppLanguageStandards)

    addStringOption(.PreBuildPhaseRunScript, [.TargetSpecializable])
    addStringOption(.PostBuildPhaseRunScript, [.TargetSpecializable])
    addStringOption(.BuildActionPreActionScript, [.TargetSpecializable, .SupportsInheritKeyword])
    addStringOption(.LaunchActionPreActionScript, [.TargetSpecializable, .SupportsInheritKeyword])
    addStringOption(.TestActionPreActionScript, [.TargetSpecializable, .SupportsInheritKeyword])
    addStringOption(.BuildActionPostActionScript, [.TargetSpecializable, .SupportsInheritKeyword])
    addStringOption(.LaunchActionPostActionScript, [.TargetSpecializable, .SupportsInheritKeyword])
    addStringOption(.TestActionPostActionScript, [.TargetSpecializable, .SupportsInheritKeyword])

    addStringOption(.BazelPath, [.Hidden, .PerUserOnly])
    addStringOption(.WorkspaceRootPath, [.Hidden, .PerUserOnly])
  }

  private func populateOptionGroupInfoWithBundle(_ bundle: Bundle) {
    for (_, keyGroup) in TulsiOptionSet.OptionKeyGroups {
      if optionKeyGroupInfo[keyGroup] == nil {
        let key = keyGroup.rawValue
        let displayName = NSLocalizedString(key, tableName: "Options", bundle: bundle, comment: "")
        let descriptionKey = key + TulsiOptionSet.DescriptionStringKeySuffix
        let description = NSLocalizedString(descriptionKey, tableName: "Options", bundle: bundle, comment: "")
        optionKeyGroupInfo[keyGroup] = (displayName, description)
      }
    }
  }
}

public func ==(lhs: TulsiOptionSet, rhs: TulsiOptionSet) -> Bool {
  for (key, option) in lhs.options {
    if rhs[key] != option {
      return false
    }
  }
  return true
}
