/*
 * 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 <android-base/unique_fd.h>

// libbase
using android::base::unique_fd;

// 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(const string& name, const unique_fd& 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(const string& name, const unique_fd& 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(unique_fd* read_side, unique_fd* write_side) {
  int fds[2];
  unique_fd 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;

  unique_fd return_fd;
  unique_fd read_fd;
  unique_fd 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<unique_fd> array;
  array.resize(2);

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

  vector<unique_fd> repeated;
  vector<unique_fd> 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
