/*
 * Copyright (C) 2016 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_utf8_strings.h"

#include <android-base/logging.h>
#include <binder/Status.h>
#include <utils/StrongPointer.h>

#include <memory>
#include <string>
#include <vector>

#include "android/aidl/tests/ITestService.h"
#include "test_helpers.h"

// libutils:
using android::sp;

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

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

using std::unique_ptr;
using std::string;
using std::vector;

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

bool ConfirmUtf8InCppStringRepeat(const sp<ITestService>& s) {
  const vector<string> utf8_inputs = {
    string("Deliver us from evil."),
    string(),
    string("\0\0", 2),
    // Similarly, the utf8 encodings of the small letter yee and euro sign.
    string("\xF0\x90\x90\xB7\xE2\x82\xAC"),
  };
  LOG(INFO) << "Confirming repeating utf8 strings works.";

  for (const auto& input : utf8_inputs) {
    string reply;
    Status status = s->RepeatUtf8CppString(input, &reply);
    if (!status.isOk() || input != reply) {
      LOG(ERROR) << "Failed while requesting service to repeat utf8 string=\""
                 << input
                 << "\". Got status=" << status.toString8()
                 << " and output=" << reply;
      return false;
    }
  }

  unique_ptr<string> ret;
  Status repeat_null_status = s->RepeatNullableUtf8CppString(nullptr, &ret);
  if (!repeat_null_status.isOk() || ret) {
    LOG(ERROR) << "RepeatNullableUtf8CppString(null) did not return null";
    return false;
  }

  for (const auto& input : utf8_inputs) {
    unique_ptr<string> reply;
    Status status = s->RepeatNullableUtf8CppString(
        unique_ptr<string>(new string(input)), &reply);
    if (!status.isOk()) {
      LOG(ERROR) << "Got status=" << status.toString8() << " while repeating "
                    "nullable utf8 string " << input;
      return false;
    }
    if (!reply) {
      LOG(ERROR) << "Got null reply while repeating nullable utf8 string "
                 << input;
      return false;
    }
    if (input != *reply) {
      LOG(ERROR) << "Failed while requesting service to repeat utf8 string=\""
                 << input
                 << "\". Got status=" << status.toString8()
                 << " and output=" << *reply;
      return false;
    }
  }

  return true;
}

bool ConfirmUtf8InCppStringArrayReverse(const sp<ITestService>& s) {
  LOG(INFO) << "Confirming passing and returning utf8 string arrays works.";
  if (!ReverseArray(s, &ITestService::ReverseUtf8CppString,
                    {string{"a"}, string{}, string{"\xc3\xb8"}})) {
    return false;
  }

  return true;
}

namespace {

bool ConfirmUtf8InCppStringCollectionReverse(const sp<ITestService>& s,
     Status (ITestService::*m)(const unique_ptr<vector<unique_ptr<string>>>&,
                               unique_ptr<vector<unique_ptr<string>>>*,
                               unique_ptr<vector<unique_ptr<string>>>*)) {
  (void)m;
  LOG(INFO) << "Confirming reversing a list of utf8 strings works";
  unique_ptr<vector<unique_ptr<string>>> input, reversed, repeated;
  Status status = (s.get()->*m)(input, &reversed, &repeated);
  if (!status.isOk() || reversed || repeated) {
    LOG(ERROR) << "Reversing null list of utf8 strings failed.";
    return false;
  }

  input.reset(new vector<unique_ptr<string>>);
  input->emplace_back(new string("Deliver us from evil."));
  input->emplace_back(nullptr);
  input->emplace_back(new string("\xF0\x90\x90\xB7\xE2\x82\xAC"));

  status = s->ReverseUtf8CppStringList(input, &repeated, &reversed);
  if (!status.isOk() || !reversed || !repeated) {
    LOG(ERROR) << "Reversing list of utf8 strings failed.";
    return false;
  }
  if (reversed->size() != input->size() || repeated->size() != input->size()) {
    LOG(ERROR) << "Bad output sizes.";
    return false;
  }

  for (size_t i = 0; i < input->size(); ++i) {
    const string* input_str = (*input)[i].get();
    const string* repeated_str = (*repeated)[i].get();
    const string* reversed_str = (*reversed)[(reversed->size() - 1) - i].get();
    if (!input_str) {
      if(repeated_str || reversed_str) {
        LOG(ERROR) << "Expected null values, but got non-null.";
        return false;
      }
      // 3 nullptrs to strings.  No need to compare values.
      continue;
    }
    if (!repeated_str || !reversed_str) {
      LOG(ERROR) << "Expected non-null values, but got null.";
      return false;
    }
    if (*input_str != *repeated_str || *input_str != *reversed_str) {
      LOG(ERROR) << "Expected '" << *input_str << "' but got "
                 << "repeated='" << *repeated_str << "' and "
                 << "reversed='" << *reversed_str;
      return false;
    }
  }
  return true;
}

}  // namespace

bool ConfirmUtf8InCppStringListReverse(const sp<ITestService>& s) {
  return ConfirmUtf8InCppStringCollectionReverse(s,
      &ITestService::ReverseUtf8CppStringList);
}

bool ConfirmUtf8InCppNullableStringArrayReverse(const sp<ITestService>& s) {
  return ConfirmUtf8InCppStringCollectionReverse(s,
      &ITestService::ReverseNullableUtf8CppString);
}

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