// RUN: %target-run-simple-swift | %FileCheck %s
// REQUIRES: executable_test
// REQUIRES: objc_interop
// UNSUPPORTED: OS=tvos
// UNSUPPORTED: OS=watchos

import Foundation

final class Foo<T: NSCoding>: NSObject, NSCoding {
  var one, two: T

  init(one: T, two: T) {
    self.one = one
    self.two = two
  }

  @objc required convenience init(coder: NSCoder) {
    let one = coder.decodeObject(forKey: "one") as! T
    let two = coder.decodeObject(forKey :"two") as! T
    self.init(one: one, two: two)
  }

  @objc(encodeWithCoder:) func encode(with encoder: NSCoder) {
    encoder.encode(one, forKey: "one")
    encoder.encode(two, forKey: "two")
  }
}

// FIXME: W* macro equivalents should be in the Darwin/Glibc overlay
func WIFEXITED(_ status: Int32) -> Bool {
  return (status & 0o177) == 0
}
func WEXITSTATUS(_ status: Int32) -> Int32 {
  return (status >> 8) & 0xFF
}

// FIXME: "environ" should be in the Darwin overlay too
@_silgen_name("_NSGetEnviron")
func _NSGetEnviron() -> UnsafeMutablePointer<UnsafeMutablePointer<UnsafeMutablePointer<CChar>?>>

var environ: UnsafeMutablePointer<UnsafeMutablePointer<CChar>?> {
  return _NSGetEnviron().pointee
}

func driver() {
  // Create a pipe to connect the archiver to the unarchiver.
  var pipes: [Int32] = [0, 0]
  guard pipe(&pipes) == 0 else { fatalError("pipe failed") }

  let pipeRead = pipes[0], pipeWrite = pipes[1]

  var archiver: pid_t = 0, unarchiver: pid_t = 0

  let envp = environ

  do {
    // Set up the archiver's stdout to feed into our pipe.
    var archiverActions: posix_spawn_file_actions_t?
    guard posix_spawn_file_actions_init(&archiverActions) == 0 else {
      fatalError("posix_spawn_file_actions_init failed")
    }
    defer { posix_spawn_file_actions_destroy(&archiverActions) }
    guard posix_spawn_file_actions_adddup2(&archiverActions,
                                           pipeWrite,
                                           STDOUT_FILENO) == 0
       && posix_spawn_file_actions_addclose(&archiverActions,
                                            pipeRead) == 0
       else {
      fatalError("posix_spawn_file_actions_add failed")
    }

    // Spawn the archiver process.
    let str: StaticString = "-archive"
    let optStr = UnsafeMutableRawPointer(mutating: str.utf8Start).bindMemory(
      to: CChar.self, capacity: str.utf8CodeUnitCount)
    let archiverArgv: [UnsafeMutablePointer<Int8>?] = [
      CommandLine.unsafeArgv[0], optStr, nil
    ]
    guard posix_spawn(&archiver, CommandLine.unsafeArgv[0],
                      &archiverActions, nil,
                      archiverArgv, envp) == 0 else {
      fatalError("posix_spawn failed")
    }
  }

  do {
    // Set up the unarchiver's stdin to read from our pipe.
    var unarchiverActions: posix_spawn_file_actions_t?
    guard posix_spawn_file_actions_init(&unarchiverActions) == 0 else {
      fatalError("posix_spawn_file_actions_init failed")
    }
    defer { posix_spawn_file_actions_destroy(&unarchiverActions) }
    guard posix_spawn_file_actions_adddup2(&unarchiverActions,
                                           pipeRead,
                                           STDIN_FILENO) == 0
       && posix_spawn_file_actions_addclose(&unarchiverActions,
                                            pipeWrite) == 0
       else {
      fatalError("posix_spawn_file_actions_add failed")
    }

    // Spawn the unarchiver process.
    let str = "-unarchive" as StaticString
    let optStr = UnsafeMutableRawPointer(mutating: str.utf8Start).bindMemory(
      to: CChar.self, capacity: str.utf8CodeUnitCount)
    var unarchiver: pid_t = 0
    let unarchiverArgv: [UnsafeMutablePointer<Int8>?] = [
      CommandLine.unsafeArgv[0], optStr, nil
    ]
    guard posix_spawn(&unarchiver, CommandLine.unsafeArgv[0],
                      &unarchiverActions, nil,
                      unarchiverArgv, envp) == 0 else {
      fatalError("posix_spawn failed")
    }
  }

  // Wash our hands of the pipe, now that the subprocesses have started.
  close(pipeRead)
  close(pipeWrite)

  // Wait for the subprocesses to finish.
  var waiting: Set<pid_t> = [archiver, unarchiver]
  while !waiting.isEmpty {
    var status: Int32 = 0
    let pid = wait(&status)
    if pid == -1 {
      // If the error was EINTR, just wait again.
      if errno == EINTR { continue }
      // If we have no children to wait for, stop.
      if errno == ECHILD { break }
      fatalError("wait failed")
    }
    waiting.remove(pid)
    // Ensure the process exited successfully.
    guard WIFEXITED(status) && WEXITSTATUS(status) == 0 else {
      fatalError("subprocess exited abnormally")
    }
  }
}

func archive() {
  let data = NSMutableData()
  let archiver = NSKeyedArchiver(forWritingWith: data)
  archiver.encode(Foo<NSString>(one: "one", two: "two"), forKey: "strings")
  archiver.encode(Foo<NSNumber>(one: 1, two: 2), forKey: "numbers")
  archiver.finishEncoding()

  // Output the archived data over stdout, which should be piped to stdin
  // on the unarchiver process.
  while true {
    let status = write(STDOUT_FILENO, data.bytes, data.length)
    if status == data.length { break }
    if errno == EINTR { continue }
    fatalError("write failed")
  }
}

func unarchive() {
  // FIXME: Pre-instantiate the generic classes that were archived, since
  // the ObjC runtime doesn't know how.
  NSStringFromClass(Foo<NSNumber>.self)
  NSStringFromClass(Foo<NSString>.self)

  // Read in the data from stdin, where the archiver process should have
  // written it.
  var rawData: [UInt8] = []

  var buffer = [UInt8](repeating: 0, count: 4096)

  while true {
    let count = read(STDIN_FILENO, &buffer, 4096)
    if count == 0 { break }
    if count == -1 {
      if errno == EINTR { continue }
      fatalError("read failed")
    }
    rawData += buffer[0..<count]
  }

  // Feed it into an unarchiver.
  let data = NSData(bytes: rawData, length: rawData.count)
  let unarchiver = NSKeyedUnarchiver(forReadingWith: data as Data)

  guard let strings
      = unarchiver.decodeObject(forKey: "strings") as? Foo<NSString> else {
    fatalError("unable to unarchive Foo<NSString>")
  }
  guard let numbers
      = unarchiver.decodeObject(forKey: "numbers") as? Foo<NSNumber> else {
    fatalError("unable to unarchive Foo<NSNumber>")
  }

  // CHECK-LABEL: <_TtGC4main3FooCSo8NSString_: {{0x[0-9a-f]+}}> #0
  // CHECK:         one: one
  // CHECK:         two: two
  // CHECK-LABEL: <_TtGC4main3FooCSo8NSNumber_: {{0x[0-9a-f]+}}> #0
  // CHECK:         one: 1
  // CHECK:         two: 2
  dump(strings)
  dump(numbers)
}

// Pick a mode based on the command-line arguments.
// The test launches as a "driver" which then respawns itself into reader
// and writer subprocesses.
if CommandLine.arguments.count < 2 {
  driver()
} else if CommandLine.arguments[1] == "-archive" {
  archive()
} else if CommandLine.arguments[1] == "-unarchive" {
  unarchive()
} else {
  fatalError("invalid commandline argument")
}

