// 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 a configuration which can be used to generate an Xcode project directly.
public class TulsiGeneratorConfig {

  public enum ConfigError: Error {
    /// The give input file does not exist or cannot be read.
    case badInputFilePath
    /// A per-user config was found but could not be read.
    case failedToReadAdditionalOptionsData(String)
    /// Deserialization failed with the given debug info.
    case deserializationFailed(String)
    /// Serialization failed with the given debug info.
    case serializationFailed(String)
  }

  /// The file extension used when saving generator configs.
  public static let FileExtension = "tulsigen"

  /// Filename to be used when writing out user-specific values.
  public static var perUserFilename: String {
    return "\(NSUserName()).tulsigen-user"
  }

  /// The name of the Xcode project.
  public let projectName: String

  public var defaultFilename: String {
    return TulsiGeneratorConfig.sanitizeFilename("\(projectName).\(TulsiGeneratorConfig.FileExtension)")
  }

  /// The name of the Xcode project that will be generated by this config.
  public var xcodeProjectFilename: String {
    return TulsiGeneratorConfig.sanitizeFilename("\(projectName).xcodeproj")
  }

  /// The Bazel targets to generate Xcode build targets for.
  public let buildTargetLabels: [BuildLabel]

  /// The directory paths for which source files should be included in the generated Xcode project.
  public let pathFilters: Set<String>

  /// Additional file paths to add to the Xcode project (e.g., BUILD file paths).
  public let additionalFilePaths: [String]?
  /// The options for this config.
  public let options: TulsiOptionSet

  /// URL to the Bazel binary.
  private let bazelURLValue: TulsiParameter<URL>

  /// URL to the Bazel binary, computed from bazelURLValue.
  public var bazelURL: URL {
    return bazelURLValue.value
  }

  static let ProjectNameKey = "projectName"
  static let BuildTargetsKey = "buildTargets"
  static let PathFiltersKey = "sourceFilters"
  static let AdditionalFilePathsKey = "additionalFilePaths"

  /// Returns a copy of the given filename sanitized by replacing path separators.
  public static func sanitizeFilename(_ filename: String) -> String {
    return filename.replacingOccurrences(of: "/", with: "_")
  }

  // Tries to resolve a URL to the Bazel exectuable via:
  // 1. Passed in bazelURL argument.
  // 2. BazelPath set on the TulsiOptionSet.
  // 3. BazelLocator's findBazelForWorkspaceRoot.
  //
  // If none of these succeed, this returns nil.
  public static func resolveBazelURL(_ bazelURL: URL?,
                                     options: TulsiOptionSet) -> TulsiParameter<URL>? {
    if let bazelURL = bazelURL {
      return TulsiParameter(value: bazelURL, source: .explicitlyProvided)
    } else if let savedBazelPath = options[.BazelPath].commonValue {
      return TulsiParameter(value: URL(fileURLWithPath: savedBazelPath), source: .options)
    } else if let locatedURL = BazelLocator.bazelURL {
      return TulsiParameter(value: locatedURL, source: .fallback)
    }
    return nil
  }

  public static func load(_ inputFile: URL, bazelURL: URL? = nil) throws -> TulsiGeneratorConfig {
    let fileManager = FileManager.default
    guard let data = fileManager.contents(atPath: inputFile.path) else {
      throw ConfigError.badInputFilePath
    }

    let additionalOptionData: Data?
    let optionsFolderURL = inputFile.deletingLastPathComponent()
    let additionalOptionsFileURL = optionsFolderURL.appendingPathComponent(TulsiGeneratorConfig.perUserFilename)
    let perUserPath = additionalOptionsFileURL.path
    if fileManager.isReadableFile(atPath: perUserPath) {
      additionalOptionData = fileManager.contents(atPath: perUserPath)
      if additionalOptionData == nil {
        throw ConfigError.failedToReadAdditionalOptionsData("Could not read file at path \(perUserPath)")
      }
    } else {
      additionalOptionData = nil
    }

    return try TulsiGeneratorConfig(data: data,
                                    additionalOptionData: additionalOptionData,
                                    bazelURL: bazelURL)
  }

  public init(projectName: String,
              buildTargetLabels: [BuildLabel],
              pathFilters: Set<String>,
              additionalFilePaths: [String]?,
              options: TulsiOptionSet,
              bazelURL: TulsiParameter<URL>) {
    self.projectName = projectName
    self.buildTargetLabels = buildTargetLabels
    self.pathFilters = pathFilters
    self.additionalFilePaths = additionalFilePaths
    self.options = options
    self.bazelURLValue = bazelURL
  }

  public convenience init(projectName: String,
                          buildTargets: [RuleInfo],
                          pathFilters: Set<String>,
                          additionalFilePaths: [String]?,
                          options: TulsiOptionSet,
                          bazelURL: TulsiParameter<URL>) {
    self.init(projectName: projectName,
              buildTargetLabels: buildTargets.map({ $0.label }),
              pathFilters: pathFilters,
              additionalFilePaths: additionalFilePaths,
              options: options,
              bazelURL: bazelURL)
  }

  public convenience init(data: Data,
                          additionalOptionData: Data? = nil,
                          bazelURL: URL? = nil) throws {
    func extractJSONDict(_ data: Data, errorBuilder: (String) -> ConfigError) throws -> [String: AnyObject] {
      do {
        guard let jsonDict = try JSONSerialization.jsonObject(with: data,
                                                                        options: JSONSerialization.ReadingOptions()) as? [String: AnyObject] else {
          throw errorBuilder("Config file contents are invalid")
        }
        return jsonDict
      } catch let e as ConfigError {
        throw e
      } catch let e as NSError {
        throw errorBuilder(e.localizedDescription)
      } catch {
        assertionFailure("Unexpected exception")
        throw errorBuilder("Unexpected exception")
      }
    }

    let dict = try extractJSONDict(data) { ConfigError.deserializationFailed($0)}

    let projectName = dict[TulsiGeneratorConfig.ProjectNameKey] as? String ?? "Unnamed Tulsi Project"
    let buildTargetLabels = dict[TulsiGeneratorConfig.BuildTargetsKey] as? [String] ?? []
    let additionalFilePaths = dict[TulsiGeneratorConfig.AdditionalFilePathsKey] as? [String]
    let rawPathFilters = Set<String>(dict[TulsiGeneratorConfig.PathFiltersKey] as? [String] ?? [])

    // While //foo/bar is a valid filesystem path, Xcode won't open a project with such a path in
    // its structures, leading to arduous debug process.
    if let badPath = additionalFilePaths?.first(where: { $0.hasPrefix("//") }) {
      throw ConfigError.deserializationFailed("Invalid additional file path: \(badPath)")
    }


    // Convert any path filters specified as build labels to their package paths.
    var pathFilters = Set<String>()
    for sourceTarget in rawPathFilters {
      if let packageName = BuildLabel(sourceTarget).packageName {
        pathFilters.insert(packageName)
      }
    }

    var optionsDict = TulsiOptionSet.getOptionsFromContainerDictionary(dict) ?? [:]
    if let additionalOptionData = additionalOptionData {
      let additionalOptions = try extractJSONDict(additionalOptionData) {
        ConfigError.failedToReadAdditionalOptionsData($0)
      }
      guard let newOptions = TulsiOptionSet.getOptionsFromContainerDictionary(additionalOptions) else {
        throw ConfigError.failedToReadAdditionalOptionsData("Invalid per-user options file")
      }
      for (key, value) in newOptions {
        optionsDict[key] = value
      }
    }
    let options = TulsiOptionSet(fromDictionary: optionsDict)

    guard let bazelURL = TulsiGeneratorConfig.resolveBazelURL(bazelURL, options: options) else {
      throw ConfigError.deserializationFailed("Unable to find Bazel Path")
    }

    self.init(projectName: projectName,
              buildTargetLabels: buildTargetLabels.map({ BuildLabel($0) }),
              pathFilters: pathFilters,
              additionalFilePaths: additionalFilePaths,
              options: options,
              bazelURL: bazelURL)
  }

  public func save() throws -> NSData {
    let sortedBuildTargetLabels = buildTargetLabels.map({ $0.value }).sorted()
    let sortedPathFilters = [String](pathFilters).sorted()
    var dict: [String: Any] = [
        TulsiGeneratorConfig.ProjectNameKey: projectName as AnyObject,
        TulsiGeneratorConfig.BuildTargetsKey: sortedBuildTargetLabels as AnyObject,
        TulsiGeneratorConfig.PathFiltersKey: sortedPathFilters as AnyObject,
    ]
    if let additionalFilePaths = additionalFilePaths {
      dict[TulsiGeneratorConfig.AdditionalFilePathsKey] = additionalFilePaths as AnyObject?
    }
    options.saveShareableOptionsIntoDictionary(&dict)

    do {
      return try JSONSerialization.tulsi_newlineTerminatedDataWithJSONObject(dict,
                                                                             options: .prettyPrinted)
    } catch let e as NSError {
      throw ConfigError.serializationFailed(e.localizedDescription)
    } catch {
      throw ConfigError.serializationFailed("Unexpected exception")
    }
  }

  public func savePerUserSettings() throws -> NSData? {
    var dict = [String: Any]()
    options.savePerUserOptionsIntoDictionary(&dict)
    if dict.isEmpty { return nil }
    do {
      return try JSONSerialization.tulsi_newlineTerminatedDataWithJSONObject(dict,
                                                                             options: .prettyPrinted)
    } catch let e as NSError {
      throw ConfigError.serializationFailed(e.localizedDescription)
    } catch {
      throw ConfigError.serializationFailed("Unexpected exception")
    }
  }

  public func configByResolvingInheritedSettingsFromProject(_ project: TulsiProject) -> TulsiGeneratorConfig {
    let resolvedOptions = options.optionSetByInheritingFrom(project.options)
    let newBazelURL = bazelURLValue.reduce(TulsiParameter(value: project.bazelURL, source: .project))
    return TulsiGeneratorConfig(projectName: projectName,
                                buildTargetLabels: buildTargetLabels,
                                pathFilters: pathFilters,
                                additionalFilePaths: additionalFilePaths,
                                options: resolvedOptions,
                                bazelURL: newBazelURL)
  }

  public func configByAppendingPathFilters(_ additionalPathFilters: Set<String>) -> TulsiGeneratorConfig {
    let newPathFilters = pathFilters.union(additionalPathFilters)
    return TulsiGeneratorConfig(projectName: projectName,
                                buildTargetLabels: buildTargetLabels,
                                pathFilters: newPathFilters,
                                additionalFilePaths: additionalFilePaths,
                                options: options,
                                bazelURL: bazelURLValue)
  }
}
