/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements. See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership. The ASF licenses this file
 * to you 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

public struct TBinaryProtocolVersion {
  static let version1    = Int32(bitPattern: 0x80010000)
  static let versionMask = Int32(bitPattern: 0xffff0000)
}

public class TBinaryProtocol: TProtocol {
  public var messageSizeLimit: UInt32  = 0
  
  public var transport: TTransport
  
  // class level properties for setting global config (useful for server in lieu of Factory design)
  public static var strictRead: Bool = false
  public static var strictWrite: Bool = true

  private var strictRead: Bool
  private var strictWrite: Bool
  
  var currentMessageName: String?
  var currentFieldName: String?
  
  
  public convenience init(transport: TTransport, strictRead: Bool, strictWrite: Bool) {
    self.init(on: transport)
    self.strictRead = strictRead
    self.strictWrite = strictWrite
  }
  
  public required init(on transport: TTransport) {
    self.transport = transport
    self.strictWrite = TBinaryProtocol.strictWrite
    self.strictRead = TBinaryProtocol.strictRead
  }
  
  func readStringBody(_ size: Int) throws -> String {
    
    var data = Data()
    try ProtocolTransportTry(error: TProtocolError(message: "Transport read failed")) {
      data = try self.transport.readAll(size: size)
    }
    
    return String(data: data, encoding: String.Encoding.utf8) ?? ""
  }
  
  /// Mark: - TProtocol
  
  public func readMessageBegin() throws -> (String, TMessageType, Int32) {
    let size: Int32 = try read()
    var messageName = ""
    var type = TMessageType.exception
    
    if size < 0 {
      let version = size & TBinaryProtocolVersion.versionMask
      if version != TBinaryProtocolVersion.version1 {
        throw TProtocolError(error: .badVersion(expected: "\(TBinaryProtocolVersion.version1)",
                                                got: "\(version)"))
      }
      type = TMessageType(rawValue: Int32(size) & 0x00FF) ?? type
      messageName = try read()
    } else {
      if strictRead {
        let errorMessage = "Missing message version, old client? Message Name: \(currentMessageName ?? "")"
        throw TProtocolError(error: .invalidData,
                             message: errorMessage)
      }
      if messageSizeLimit > 0 && size > Int32(messageSizeLimit) {
        throw TProtocolError(error: .sizeLimit(limit: Int(messageSizeLimit), got: Int(size)))
      }
      
      messageName = try readStringBody(Int(size))
      type = TMessageType(rawValue: Int32(try read() as UInt8)) ?? type
    }
    
    let seqID: Int32 = try read()
    return (messageName, type, seqID)
  }
  
  public func readMessageEnd() throws {
    return
  }
  
  public func readStructBegin() throws -> String {
    return ""
  }
  
  public func readStructEnd() throws {
    return
  }
  
  public func readFieldBegin() throws -> (String, TType, Int32) {
    
    let fieldType = TType(rawValue: Int32(try read() as UInt8)) ?? TType.stop
    var fieldID: Int32 = 0
    
    if fieldType != .stop {
      fieldID = Int32(try read() as Int16)
    }
    
    return ("", fieldType, fieldID)
  }
  
  public func readFieldEnd() throws {
    return
  }
  
  public func readMapBegin() throws -> (TType, TType, Int32) {
    var raw = Int32(try read() as UInt8)
    guard let keyType = TType(rawValue: raw) else {
      throw TProtocolError(message: "Unknown value for keyType TType: \(raw)")
    }
    
    raw = Int32(try read() as UInt8)
    guard let valueType = TType(rawValue: raw) else {
      throw TProtocolError(message: "Unknown value for valueType TType: \(raw)")
    }
    let size: Int32 = try read()
    
    return (keyType, valueType, size)
  }
  
  public func readMapEnd() throws {
    return
  }
  
  public func readSetBegin() throws -> (TType, Int32) {
    let raw = Int32(try read() as UInt8)
    guard let elementType = TType(rawValue: raw) else {
      throw TProtocolError(message: "Unknown value for elementType TType: \(raw)")
    }
    
    let size: Int32 = try read()
    
    return (elementType, size)
  }
  
  public func readSetEnd() throws {
    return
  }
  
  public func readListBegin() throws -> (TType, Int32) {
    let raw = Int32(try read() as UInt8)
    guard let elementType = TType(rawValue: raw) else {
      throw TProtocolError(message: "Unknown value for elementType TType: \(raw)")
    }
    let size: Int32 = try read()
    
    return (elementType, size)
  }
  
  public func readListEnd() throws {
    return
  }
  
  public func read() throws -> String {
    let data: Data = try read()
    guard let str = String.init(data: data, encoding: .utf8) else {
      throw TProtocolError(error: .invalidData, message: "Couldn't encode UTF-8 from data read")
    }
    return str
  }
  
  public func read() throws -> Bool {
    return (try read() as UInt8) == 1
  }
  
  public func read() throws -> UInt8 {
    var buff = Data()
    try ProtocolTransportTry(error: TProtocolError(message: "Transport Read Failed")) {
      buff = try self.transport.readAll(size: 1)
    }
    return buff[0]
  }
  
  public func read() throws -> Int8 {
    var buff = Data()
    try ProtocolTransportTry(error: TProtocolError(message: "Transport Read Failed")) {
      buff = try self.transport.readAll(size: 1)
    }
    return buff.withUnsafeBytes { pntr in
      return pntr.load(as: Int8.self)
    }
  }
  
  public func read() throws -> Int16 {
    var buff = Data()
    try ProtocolTransportTry(error: TProtocolError(message: "Transport Read Failed")) {
      buff = try self.transport.readAll(size: 2)
    }
    var ret = Int16(buff[0] & 0xff) << 8
    ret |=    Int16(buff[1] & 0xff)
    return ret
  }
  
  public func read() throws -> Int32 {
    var buff = Data()
    try ProtocolTransportTry(error: TProtocolError(message: "Transport Read Failed")) {
      buff = try self.transport.readAll(size: 4)
    }
    var ret = Int32(buff[0] & 0xff) << 24
    ret |=    Int32(buff[1] & 0xff) << 16
    ret |=    Int32(buff[2] & 0xff) << 8
    ret |=    Int32(buff[3] & 0xff)
    
    return ret
  }
  
  public func read() throws -> Int64 {
    var buff = Data()
    try ProtocolTransportTry(error: TProtocolError(message: "Transport Read Failed")) {
      buff = try self.transport.readAll(size: 8)
    }
    var ret = Int64(buff[0] & 0xff) << 56
    ret |=    Int64(buff[1] & 0xff) << 48
    ret |=    Int64(buff[2] & 0xff) << 40
    ret |=    Int64(buff[3] & 0xff) << 32
    ret |=    Int64(buff[4] & 0xff) << 24
    ret |=    Int64(buff[5] & 0xff) << 16
    ret |=    Int64(buff[6] & 0xff) << 8
    ret |=    Int64(buff[7] & 0xff)
    
    return ret
  }
  
  public func read() throws -> Double {
    let val = try read() as Int64
    return Double(bitPattern: UInt64(bitPattern: val))
  }
  
  public func read() throws -> Data {
    let size = Int(try read() as Int32)
    var data = Data()
    try ProtocolTransportTry(error: TProtocolError(message: "Transport Read Failed")) {
      data = try self.transport.readAll(size: size)
    }
    
    return data
  }
  
  public func read() throws -> UUID {
    let data = try self.transport.readAll(size: 16)
    let lsb = data[0..<8]
    let msb = data[8..<16]
    
    var id = UUID().uuid
    withUnsafeMutableBytes(of: &id) { pntr in
      var copyData = msb
      copyData.append(lsb)
      copyData.copyBytes(to: pntr)
    }
    return UUID(uuid: id)
  }
  
  // Write methods
  
  public func writeMessageBegin(name: String, type messageType: TMessageType, sequenceID: Int32) throws {
    if strictWrite {
      let version = TBinaryProtocolVersion.version1 | Int32(messageType.rawValue)
      try write(version)
      try write(name)
      try write(sequenceID)
    } else {
      try write(name)
      try write(UInt8(messageType.rawValue))
      try write(sequenceID)
    }
    currentMessageName = name
  }
  
  public func writeMessageEnd() throws {
    currentMessageName = nil
  }
  
  public func writeStructBegin(name: String) throws {
    return
  }
  
  public func writeStructEnd() throws {
    return
  }
  
  public func writeFieldBegin(name: String, type fieldType: TType, fieldID: Int32) throws {
    try write(UInt8(fieldType.rawValue))
    try write(Int16(fieldID))
  }
  
  public func writeFieldStop() throws {
    try write(UInt8(TType.stop.rawValue))
  }
  
  public func writeFieldEnd() throws {
    return
  }
  
  public func writeMapBegin(keyType: TType, valueType: TType, size: Int32) throws {
    try write(UInt8(keyType.rawValue))
    try write(UInt8(valueType.rawValue))
    try write(size)
  }
  
  public func writeMapEnd() throws {
    return
  }
  
  public func writeSetBegin(elementType: TType, size: Int32) throws {
    try write(UInt8(elementType.rawValue))
    try write(size)
  }
  
  public func writeSetEnd() throws {
    return
  }
  
  public func writeListBegin(elementType: TType, size: Int32) throws {
    try write(UInt8(elementType.rawValue))
    try write(size)
  }
  
  public func writeListEnd() throws {
    return
  }
  
  public func write(_ value: String) throws {
    try write(value.data(using: .utf8)!)
  }
  
  public func write(_ value: Bool) throws {
    let byteVal: UInt8 = value ? 1 : 0
    try write(byteVal)
  }
  
  public func write(_ value: UInt8) throws {
    let buff = Data([value])
    
    try ProtocolTransportTry(error: TProtocolError(message: "Transport write failed")) {
      try self.transport.write(data: buff)
    }
  }
  
  public func write(_ value: Int8) throws {
    var value = value
    let buff = Data(bytes: &value, count: MemoryLayout<Int8>.size(ofValue: value))
    try ProtocolTransportTry(error: TProtocolError(message: "Transport write failed")) {
      try self.transport.write(data: buff)
    }
  }
  
  public func write(_ value: Int16) throws {
    var buff = Data()
    buff.append(Data([UInt8(0xff & (value >> 8))]))
    buff.append(Data([UInt8(0xff & (value))]))
    try ProtocolTransportTry(error: TProtocolError(message: "Transport write failed")) {
      try self.transport.write(data: buff)
    }
  }
  
  public func write(_ value: Int32) throws {
    var buff = Data()
    buff.append(Data([UInt8(0xff & (value >> 24))]))
    buff.append(Data([UInt8(0xff & (value >> 16))]))
    buff.append(Data([UInt8(0xff & (value >> 8))]))
    buff.append(Data([UInt8(0xff & (value))]))
    
    try ProtocolTransportTry(error: TProtocolError(message: "Transport write failed")) {
      try self.transport.write(data: buff)
    }
  }
  
  public func write(_ value: Int64) throws {
    var buff = Data()
    buff.append(Data([UInt8(0xff & (value >> 56))]))
    buff.append(Data([UInt8(0xff & (value >> 48))]))
    buff.append(Data([UInt8(0xff & (value >> 40))]))
    buff.append(Data([UInt8(0xff & (value >> 32))]))
    buff.append(Data([UInt8(0xff & (value >> 24))]))
    buff.append(Data([UInt8(0xff & (value >> 16))]))
    buff.append(Data([UInt8(0xff & (value >> 8))]))
    buff.append(Data([UInt8(0xff & (value))]))
    
    try ProtocolTransportTry(error: TProtocolError(message: "Transport write failed")) {
      try self.transport.write(data: buff)
    }
  }
  
  public func write(_ value: Double) throws {
    // Notably unsafe, since Double and Int64 are the same size, this should work fine
    try self.write(Int64(bitPattern: value.bitPattern))
  }
  
  public func write(_ data: Data) throws {
    try write(Int32(data.count))
    
    try ProtocolTransportTry(error: TProtocolError(message: "Transport write failed")) {
      try self.transport.write(data: data)
    }
  }
  
  public func write(_ value: UUID) throws {
    let data = withUnsafePointer(to: value.uuid) {
      Data(bytes: $0, count: MemoryLayout.size(ofValue: value.uuid))
    }
    let msb = data[0..<8]
    let lsb = data[8..<16]
    
    var buff = Data()
    buff.append(lsb)
    buff.append(msb)
    
    try self.transport.write(data: buff)
  }
}
