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

let XcodeProjectArchiveVersion = "1"


protocol PBXProjSerializable: class {
  func serializeInto(_ serializer: PBXProjFieldSerializer) throws
}


/// Methods for serializing components of a PBXObject.
protocol PBXProjFieldSerializer {
  func addField(_ name: String, _ obj: PBXObjectProtocol?, rawID: Bool) throws
  func addField(_ name: String, _ val: Int) throws
  func addField(_ name: String, _ val: Bool) throws
  func addField(_ name: String, _ val: String?) throws
  func addField(_ name: String, _ val: [String: Any]?) throws
  func addField<T: PBXObjectProtocol>(_ name: String, _ values: [T]) throws
  func addField(_ name: String, _ values: [String]) throws

  // Serializes an object if it has not already been serialized and returns its globalID, optionally
  // with a comment string attached unless returnRawID is true.
  func serializeObject(_ object: PBXObjectProtocol, returnRawID: Bool) throws -> String
}

extension PBXProjFieldSerializer {
  func addField(_ name: String, _ obj: PBXObjectProtocol?) throws {
    try addField(name, obj, rawID: false)
  }
}


extension NSMutableData {
  enum EncodingError: Error {
    // A string failed to be encoded into NSData as UTF8.
    case stringUTF8EncodingError
  }

  func tulsi_appendString(_ str: String) throws {
    guard let encoded = str.data(using: String.Encoding.utf8) else {
      throw EncodingError.stringUTF8EncodingError
    }
    self.append(encoded)
  }
}


/// Encapsulates the ability to serialize a PBXProject into an OpenStep formatted plist.
final class OpenStepSerializer: PBXProjFieldSerializer {

  private enum SerializationError: Error {
    // A PBX object was referenced but never defined.
    case referencedObjectNotFoundError
  }

  // List of objects that are always serialized on a single line by Xcode.
  private static let CompactPBXTypes = Set<String>(["PBXBuildFile", "PBXFileReference"])

  private let rootObject: PBXProject
  private let gidGenerator: GIDGeneratorProtocol
  private var objects = [String: TypedDict]()

  private class GIDHolder {
    var gids: [String] = []
  }
  // Maps PBXObject types to arrays of keys in the objects array. This allows serialization in the
  // same OpenStep format as Xcode. A wrapper GIDHolder class is leveraged in place of directly
  // storing arrays of keys to avoid performance issues due to value semantics as the arrays are
  // mutated.
  private var typedObjectIndex = [String: GIDHolder]()

  // Dictionary containing data for the object currently being serialized.
  private var currentDict: RawDict!

  init(rootObject: PBXProject, gidGenerator: GIDGeneratorProtocol) {
    self.rootObject = rootObject
    self.gidGenerator = gidGenerator
  }

  func serialize() -> Data? {
    do {
      let rootObjectID = try serializeObject(rootObject)
      return serializeObjectDictionaryWithRoot(rootObjectID)
    } catch {
      return nil
    }
  }

  // MARK: - XcodeProjFieldSerializer
  func serializeObject(_ obj: PBXObjectProtocol, returnRawID: Bool = false) throws -> String {
    if let typedObject = objects[obj.globalID] {
      if !returnRawID {
        return "\(obj.globalID)\(typedObject.comment)"
      }
      return obj.globalID
    }

    // If the object doesn't have a GID from a previous serialization, generate one.
    if obj.globalID.isEmpty {
      obj.globalID = gidGenerator.generate(obj)
    }

    let globalID = obj.globalID
    let isa = obj.isa
    let serializationDict = TypedDict(gid: globalID, isa: isa, comment: obj.comment)
    let stack = currentDict
    currentDict = serializationDict

    // Note: The object must be added to the objects dictionary prior to serialization in order to
    // allow recursive references. e.g., PBXTargetDependency instances between targets in the same
    // PBXProject instance.
    objects[globalID] = serializationDict

    try obj.serializeInto(self)

    var objectGIDHolder = typedObjectIndex[isa]
    if objectGIDHolder == nil {
      objectGIDHolder = GIDHolder()
      typedObjectIndex[isa] = objectGIDHolder
    }
    objectGIDHolder!.gids.append(globalID)

    currentDict = stack

    if returnRawID {
      return globalID
    }
    return "\(globalID)\(serializationDict.comment)"
  }

  func addField(_ name: String, _ obj: PBXObjectProtocol?, rawID: Bool) throws {
    guard let local = obj else {
      return
    }

    let gid = try serializeObject(local, returnRawID: rawID)
    currentDict.dict[name] = gid as AnyObject?
  }

  func addField(_ name: String, _ val: Int) throws {
    currentDict.dict[name] = val as AnyObject?
  }

  func addField(_ name: String, _ val: Bool) throws {
    let intVal = val ? 1 : 0
    currentDict.dict[name] = intVal as AnyObject?
  }

  func addField(_ name: String, _ val: String?) throws {
    guard let stringValue = val else {
      return
    }

    currentDict.dict[name] = escapeString(stringValue) as AnyObject?
  }

  func addField(_ name: String, _ val: [String: Any]?) throws {
    // Note: Xcode will crash if empty buildSettings member dictionaries of XCBuildConfiguration's
    // are omitted so this does not check to see if the dictionary is empty or not.
    guard let dict = val else {
      return
    }

    let stack = currentDict
    currentDict = RawDict(compact: (stack?.compact)!)
    for (key, value) in dict {
      if let stringValue = value as? String {
        currentDict.dict[key] = escapeString(stringValue) as AnyObject?
      } else if let dictValue = value as? [String: AnyObject] {
        try addField(key, dictValue)
      } else if let arrayValue = value as? [String] {
        try addField(key, arrayValue)
      } else {
        assertionFailure("Unsupported complex object \(value) in nested dictionary type")
      }
    }
    stack?.dict[name] = currentDict
    currentDict = stack

  }

  func addField<T: PBXObjectProtocol>(_ name: String, _ values: [T]) throws {
    currentDict.dict[name] = try values.map() { try serializeObject($0) }
  }

  func addField(_ name: String, _ values: [String]) throws {
    currentDict.dict[name] = values.map() { escapeString($0) }
  }

  func getGlobalIDForObject(_ object: PBXObjectProtocol) throws -> String {
    return try serializeObject(object)
  }

  // MARK: - Private methods

  private func serializeObjectDictionaryWithRoot(_ rootObjectID: String) -> Data? {
    let data = NSMutableData()
    do {
      try data.tulsi_appendString("// !$*UTF8*$!\n{\n")
      var indent = "\t"

      func appendIndentedString(_ value: String) throws {
        try data.tulsi_appendString(indent + value)
      }

      try appendIndentedString("archiveVersion = \(XcodeProjectArchiveVersion);\n")
      try appendIndentedString("classes = {\n\(indent)};\n")
      try appendIndentedString("objectVersion = \(XcodeVersionInfo.objectVersion);\n")

      try appendIndentedString("objects = {\n")
      let oldIndent = indent
      indent += "\t"

      try encodeSerializedPBXObjectArray("PBXBuildFile", into: data, indented: indent)
      try encodeSerializedPBXObjectArray("PBXContainerItemProxy", into: data, indented: indent)
      try encodeSerializedPBXObjectArray("PBXFileReference", into: data, indented: indent)
      try encodeSerializedPBXObjectArray("PBXGroup", into: data, indented: indent)
      try encodeSerializedPBXObjectArray("PBXLegacyTarget", into: data, indented: indent)
      try encodeSerializedPBXObjectArray("PBXNativeTarget", into: data, indented: indent)
      try encodeSerializedPBXObjectArray("PBXProject", into: data, indented: indent)
      try encodeSerializedPBXObjectArray("PBXShellScriptBuildPhase", into: data, indented: indent)
      try encodeSerializedPBXObjectArray("PBXSourcesBuildPhase", into: data, indented: indent)
      try encodeSerializedPBXObjectArray("PBXVariantGroup", into: data, indented: indent)
      try encodeSerializedPBXObjectArray("PBXTargetDependency", into: data, indented: indent)
      try encodeSerializedPBXObjectArray("XCBuildConfiguration", into: data, indented: indent)
      try encodeSerializedPBXObjectArray("XCConfigurationList", into: data, indented: indent)
      try encodeSerializedPBXObjectArray("XCVersionGroup", into: data, indented: indent)

      assert(typedObjectIndex.isEmpty, "Failed to encode objects of type(s) \(typedObjectIndex.keys)")

      indent = oldIndent
      try appendIndentedString("};\n")
      try appendIndentedString("rootObject = \(rootObjectID);\n")
      try data.tulsi_appendString("}")
    } catch {
      return nil
    }

    return data as Data
  }

  private func encodeSerializedPBXObjectArray(_ key: String,
                                              into data: NSMutableData,
                                              indented indent: String) throws {
    guard let entries = typedObjectIndex[key]?.gids else {
      return
    }

    // For debugging purposes, throw away the index now that it's being encoded.
    typedObjectIndex.removeValue(forKey: key)

    try data.tulsi_appendString("\n/* Begin \(key) section */\n")

    for gid in entries.sorted() {
      guard let obj = objects[gid] else {
        throw SerializationError.referencedObjectNotFoundError
      }

      try obj.appendToData(data, indent: indent)
    }

    try data.tulsi_appendString("/* End \(key) section */\n")
  }

  /// Intermediate representation of a raw dictionary.
  private class RawDict {
    var dict = [String: Any]()
    let compact: Bool

    init(compact: Bool = false) {
      self.compact = compact
    }

    func appendToData(_ data: NSMutableData, indent: String) throws {
      try data.tulsi_appendString("{")

      let (closingSpacer, spacer) = spacersForIndent(indent)
      if !compact {
        try data.tulsi_appendString(spacer)
      }

      try appendContentsToData(data, indent: indent, spacer: spacer)
      try data.tulsi_appendString("\(closingSpacer)};")
    }

    // MARK: - Internal methods

    func appendContentsToData(_ data: NSMutableData, indent: String, spacer: String) throws {
      let newIndent = indent + "\t"
      var leadingSpacer = ""
      for (key, value) in dict.sorted(by: { $0.0 < $1.0 }) {
        let key = escapeString(key)
        if let rawDictValue = value as? RawDict {
          try data.tulsi_appendString("\(leadingSpacer)\(key) = ")
          try rawDictValue.appendToData(data, indent: newIndent)
        } else if let arrayValue = value as? [String] {
          try data.tulsi_appendString("\(leadingSpacer)\(key) = (")
          let itemSpacer = spacer + (compact ? "" : "\t")
          try arrayValue.forEach() { try data.tulsi_appendString("\(itemSpacer)\($0),") }
          try data.tulsi_appendString("\(spacer));")
        } else {
          try data.tulsi_appendString("\(leadingSpacer)\(key) = \(value);")
        }
        leadingSpacer = spacer
      }
    }

    func spacersForIndent(_ indent: String) -> (String, String) {
      let closingSpacer: String
      let spacer: String
      if compact {
        spacer = " "
        closingSpacer = spacer
      } else {
        closingSpacer = "\n\(indent)"
        spacer = "\(closingSpacer)\t"
      }
      return (closingSpacer, spacer)
    }
  }


  /// Intermediate representation of a typed PBXObject.
  private final class TypedDict: RawDict {
    let gid: String
    let isa: String
    let comment: String

    init(gid: String, isa: String, comment: String? = nil) {
      self.gid = gid
      self.isa = isa
      if let comment = comment {
        self.comment = " /* \(comment) */"
      } else {
        self.comment = ""
      }
      super.init(compact: OpenStepSerializer.CompactPBXTypes.contains(isa))
    }

    override func appendToData(_ data: NSMutableData, indent: String) throws {
      try data.tulsi_appendString("\(indent)\(gid)\(comment) = {")

      let (closingSpacer, spacer) = spacersForIndent(indent)
      if !compact {
        try data.tulsi_appendString(spacer)
      }

      try data.tulsi_appendString("isa = \(isa);\(spacer)")
      try appendContentsToData(data, indent: indent, spacer: spacer)
      try data.tulsi_appendString("\(closingSpacer)};\n")
    }
  }
}


// Regex used to determine whether a string value can be printed without quotes or not.
private let unquotedSerializableStringRegex = try! NSRegularExpression(pattern: "^[A-Z0-9._/]+$",
                                                                       options: [.caseInsensitive])

private func escapeString(_ val: String) -> String {
  var val = val
  // The quotation marks can be omitted if the string is composed strictly of alphanumeric
  // characters and contains no white space (numbers are handled as strings in property lists).
  // Though the property list format uses ASCII for strings, note that Cocoa uses Unicode. Since
  // string encodings vary from region to region, this representation makes the format fragile.
  // You may see strings containing unreadable sequences of ASCII characters; these are used to
  // represent Unicode characters.
  let valueRange = NSMakeRange(0, val.count)
  if unquotedSerializableStringRegex.firstMatch(in: val, options: NSRegularExpression.MatchingOptions.anchored, range: valueRange) != nil {
    return val
  } else {
    val = val.replacingOccurrences(of: "\\", with: "\\\\")
    val = val.replacingOccurrences(of: "\"", with: "\\\"")
    val = val.replacingOccurrences(of: "\n", with: "\\n")
    return "\"\(val)\""
  }
}
