/*
 * Copyright (C) 2015 The Android Open Source Project
 *
 * 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.
 */

#include "aidl_test_client_file_descriptors.h"

#include <iostream>
#include <vector>

 #include <errno.h>
#include <string.h>
#include <unistd.h>

#include <nativehelper/ScopedFd.h>

// libutils:
using android::sp;

// libbinder:
using android::binder::Status;

// generated
using android::aidl::tests::ITestService;

using std::cerr;
using std::cout;
using std::endl;
using std::string;
using std::vector;

namespace android {
namespace aidl {
namespace tests {
namespace client {

#define FdByName(_fd) #_fd, _fd

bool DoWrite(string name, const ScopedFd& fd, const string& buf) {
  int wrote;

  while ((wrote = write(fd.get(), buf.data(), buf.size())) < 0 && errno == EINTR);

  if (wrote == (signed)buf.size()) {
    return true;
  }

  if (wrote < 0) {
    cerr << "Error writing to file descriptor '" << name << "': "
        << strerror(errno) << endl;
  } else {
    cerr << "File descriptor '" << name << "'accepted short data." << endl;
  }

  return false;
}

bool DoRead(string name, const ScopedFd& fd, const string& expected) {
  size_t length = expected.size();
  int got;
  string buf;
  buf.resize(length);

  while ((got = read(fd.get(), &buf[0], length)) < 0 && errno == EINTR);

  if (got < 0) {
    cerr << "Error reading from '" << name << "': " << strerror(errno) << endl;
    return false;
  }

  if (buf != expected) {
    cerr << "Expected '" << expected << "' got '" << buf << "'" << endl;
    return false;
  }

  return true;
}

bool DoPipe(ScopedFd* read_side, ScopedFd* write_side) {
  int fds[2];
  ScopedFd return_fd;

  if (pipe(fds)) {
    cout << "Error creating pipes: " << strerror(errno) << endl;
    return false;
  }

  read_side->reset(fds[0]);
  write_side->reset(fds[1]);
  return true;
}

bool ConfirmFileDescriptors(const sp<ITestService>& s) {
  Status status;
  cout << "Confirming passing and returning file descriptors works." << endl;

  ScopedFd return_fd;
  ScopedFd read_fd;
  ScopedFd write_fd;

  if (!DoPipe(&read_fd, &write_fd)) {
    return false;
  }

  status = s->RepeatFileDescriptor(write_fd, &return_fd);

  if (!status.isOk()) {
    cerr << "Could not repeat file descriptors." << endl;
    return false;
  }

  /* A note on some of the spookier stuff going on here: IIUC writes to pipes
   * should be atomic and non-blocking so long as the total size doesn't exceed
   * PIPE_BUF. We thus play a bit fast and loose with failure modes here.
   */

  bool ret =
      DoWrite(FdByName(return_fd), "ReturnString") &&
      DoRead(FdByName(read_fd), "ReturnString");

  return ret;
}

bool ConfirmFileDescriptorArrays(const sp<ITestService>& s) {
  Status status;
  cout << "Confirming passing and returning file descriptor arrays works." << endl;

  vector<ScopedFd> array;
  array.resize(2);

  if (!DoPipe(&array[0], &array[1])) {
    return false;
  }

  vector<ScopedFd> repeated;
  vector<ScopedFd> reversed;

  status = s->ReverseFileDescriptorArray(array, &repeated, &reversed);

  if (!status.isOk()) {
    cerr << "Could not reverse file descriptor array." << endl;
    return false;
  }

  bool ret =
      DoWrite(FdByName(array[1]), "First") &&
      DoWrite(FdByName(repeated[1]), "Second") &&
      DoWrite(FdByName(reversed[0]), "Third") &&
      DoRead(FdByName(reversed[1]), "FirstSecondThird");

  return ret;
}

}  // namespace client
}  // namespace tests
}  // namespace aidl
}  // namespace android
