// Copyright 2014 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include <stdio.h>

#include <algorithm>
#include <string>
#include <utility>
#include <vector>

#include "mojo/public/c/system/macros.h"
#include "mojo/public/cpp/bindings/binding.h"
#include "mojo/public/cpp/bindings/interface_ptr.h"
#include "mojo/public/cpp/bindings/lib/connector.h"
#include "mojo/public/cpp/bindings/lib/message_header_validator.h"
#include "mojo/public/cpp/bindings/lib/router.h"
#include "mojo/public/cpp/bindings/lib/validation_errors.h"
#include "mojo/public/cpp/bindings/message.h"
#include "mojo/public/cpp/bindings/tests/validation_test_input_parser.h"
#include "mojo/public/cpp/environment/environment.h"
#include "mojo/public/cpp/system/core.h"
#include "mojo/public/cpp/test_support/test_support.h"
#include "mojo/public/cpp/utility/run_loop.h"
#include "mojo/public/interfaces/bindings/tests/validation_test_interfaces.mojom.h"
#include "testing/gtest/include/gtest/gtest.h"

namespace mojo {

using internal::MessageValidator;
using internal::MessageValidatorList;
using internal::ValidationError;
using internal::ValidationErrorToString;

namespace test {
namespace {

template <typename T>
void Append(std::vector<uint8_t>* data_vector, T data) {
  size_t pos = data_vector->size();
  data_vector->resize(pos + sizeof(T));
  memcpy(&(*data_vector)[pos], &data, sizeof(T));
}

bool TestInputParser(const std::string& input,
                     bool expected_result,
                     const std::vector<uint8_t>& expected_data,
                     size_t expected_num_handles) {
  std::vector<uint8_t> data;
  size_t num_handles;
  std::string error_message;

  bool result =
      ParseValidationTestInput(input, &data, &num_handles, &error_message);
  if (expected_result) {
    if (result && error_message.empty() && expected_data == data &&
        expected_num_handles == num_handles) {
      return true;
    }

    // Compare with an empty string instead of checking |error_message.empty()|,
    // so that the message will be printed out if the two are not equal.
    EXPECT_EQ(std::string(), error_message);
    EXPECT_EQ(expected_data, data);
    EXPECT_EQ(expected_num_handles, num_handles);
    return false;
  }

  EXPECT_FALSE(error_message.empty());
  return !result && !error_message.empty();
}

std::vector<std::string> GetMatchingTests(const std::vector<std::string>& names,
                                          const std::string& prefix) {
  const std::string suffix = ".data";
  std::vector<std::string> tests;
  for (size_t i = 0; i < names.size(); ++i) {
    if (names[i].size() >= suffix.size() &&
        names[i].substr(0, prefix.size()) == prefix &&
        names[i].substr(names[i].size() - suffix.size()) == suffix)
      tests.push_back(names[i].substr(0, names[i].size() - suffix.size()));
  }
  return tests;
}

bool ReadFile(const std::string& path, std::string* result) {
  FILE* fp = OpenSourceRootRelativeFile(path.c_str());
  if (!fp) {
    ADD_FAILURE() << "File not found: " << path;
    return false;
  }
  fseek(fp, 0, SEEK_END);
  size_t size = static_cast<size_t>(ftell(fp));
  if (size == 0) {
    result->clear();
    fclose(fp);
    return true;
  }
  fseek(fp, 0, SEEK_SET);
  result->resize(size);
  size_t size_read = fread(&result->at(0), 1, size, fp);
  fclose(fp);
  return size == size_read;
}

bool ReadAndParseDataFile(const std::string& path,
                          std::vector<uint8_t>* data,
                          size_t* num_handles) {
  std::string input;
  if (!ReadFile(path, &input))
    return false;

  std::string error_message;
  if (!ParseValidationTestInput(input, data, num_handles, &error_message)) {
    ADD_FAILURE() << error_message;
    return false;
  }

  return true;
}

bool ReadResultFile(const std::string& path, std::string* result) {
  if (!ReadFile(path, result))
    return false;

  // Result files are new-line delimited text files. Remove any CRs.
  result->erase(std::remove(result->begin(), result->end(), '\r'),
                result->end());

  // Remove trailing LFs.
  size_t pos = result->find_last_not_of('\n');
  if (pos == std::string::npos)
    result->clear();
  else
    result->resize(pos + 1);

  return true;
}

std::string GetPath(const std::string& root, const std::string& suffix) {
  return "mojo/public/interfaces/bindings/tests/data/validation/" + root +
         suffix;
}

// |message| should be a newly created object.
bool ReadTestCase(const std::string& test,
                  Message* message,
                  std::string* expected) {
  std::vector<uint8_t> data;
  size_t num_handles;
  if (!ReadAndParseDataFile(GetPath(test, ".data"), &data, &num_handles) ||
      !ReadResultFile(GetPath(test, ".expected"), expected)) {
    return false;
  }

  message->AllocUninitializedData(static_cast<uint32_t>(data.size()));
  if (!data.empty())
    memcpy(message->mutable_data(), &data[0], data.size());
  message->mutable_handles()->resize(num_handles);

  return true;
}

void RunValidationTests(const std::string& prefix,
                        const MessageValidatorList& validators,
                        MessageReceiver* test_message_receiver) {
  std::vector<std::string> names =
      EnumerateSourceRootRelativeDirectory(GetPath("", ""));
  std::vector<std::string> tests = GetMatchingTests(names, prefix);

  for (size_t i = 0; i < tests.size(); ++i) {
    Message message;
    std::string expected;
    ASSERT_TRUE(ReadTestCase(tests[i], &message, &expected));

    std::string actual;
    auto result = RunValidatorsOnMessage(validators, &message, nullptr);
    if (result == ValidationError::NONE) {
      mojo_ignore_result(test_message_receiver->Accept(&message));
      actual = "PASS";
    } else {
      actual = ValidationErrorToString(result);
    }

    EXPECT_EQ(expected, actual) << "failed test: " << tests[i];
  }
}

class DummyMessageReceiver : public MessageReceiver {
 public:
  bool Accept(Message* message) override {
    return true;  // Any message is OK.
  }
};

class ValidationTest : public testing::Test {
 public:
  ~ValidationTest() override {}

 private:
  Environment env_;
};

class ValidationIntegrationTest : public ValidationTest {
 public:
  ValidationIntegrationTest() : test_message_receiver_(nullptr) {}

  ~ValidationIntegrationTest() override {}

  void SetUp() override {
    ScopedMessagePipeHandle tester_endpoint;
    ASSERT_EQ(MOJO_RESULT_OK,
              CreateMessagePipe(nullptr, &tester_endpoint, &testee_endpoint_));
    test_message_receiver_ =
        new TestMessageReceiver(this, tester_endpoint.Pass());
  }

  void TearDown() override {
    delete test_message_receiver_;
    test_message_receiver_ = nullptr;

    // Make sure that the other end receives the OnConnectionError()
    // notification.
    PumpMessages();
  }

  MessageReceiver* test_message_receiver() { return test_message_receiver_; }

  ScopedMessagePipeHandle testee_endpoint() { return testee_endpoint_.Pass(); }

 private:
  class TestMessageReceiver : public MessageReceiver {
   public:
    TestMessageReceiver(ValidationIntegrationTest* owner,
                        ScopedMessagePipeHandle handle)
        : owner_(owner), connector_(handle.Pass()) {
      connector_.set_enforce_errors_from_incoming_receiver(false);
    }
    ~TestMessageReceiver() override {}

    bool Accept(Message* message) override {
      bool rv = connector_.Accept(message);
      owner_->PumpMessages();
      return rv;
    }

   public:
    ValidationIntegrationTest* owner_;
    mojo::internal::Connector connector_;
  };

  void PumpMessages() { loop_.RunUntilIdle(); }

  RunLoop loop_;
  TestMessageReceiver* test_message_receiver_;
  ScopedMessagePipeHandle testee_endpoint_;
};

class IntegrationTestInterfaceImpl : public IntegrationTestInterface {
 public:
  ~IntegrationTestInterfaceImpl() override {}

  void Method0(BasicStructPtr param0,
               const Method0Callback& callback) override {
    callback.Run(Array<uint8_t>::New(0u));
  }
};

class FailingValidator : public mojo::internal::MessageValidator {
 public:
  explicit FailingValidator(ValidationError err) : err_(err) {}
  ValidationError Validate(const Message* message, std::string* err) override {
    return err_;
  }

 private:
  ValidationError err_;
};

TEST_F(ValidationTest, InputParser) {
  {
    // The parser, as well as Append() defined above, assumes that this code is
    // running on a little-endian platform. Test whether that is true.
    uint16_t x = 1;
    ASSERT_EQ(1, *(reinterpret_cast<char*>(&x)));
  }
  {
    // Test empty input.
    std::string input;
    std::vector<uint8_t> expected;

    EXPECT_TRUE(TestInputParser(input, true, expected, 0));
  }
  {
    // Test input that only consists of comments and whitespaces.
    std::string input = "    \t  // hello world \n\r \t// the answer is 42   ";
    std::vector<uint8_t> expected;

    EXPECT_TRUE(TestInputParser(input, true, expected, 0));
  }
  {
    std::string input =
        "[u1]0x10// hello world !! \n\r  \t [u2]65535 \n"
        "[u4]65536 [u8]0xFFFFFFFFFFFFFFFF 0 0Xff";
    std::vector<uint8_t> expected;
    Append(&expected, static_cast<uint8_t>(0x10));
    Append(&expected, static_cast<uint16_t>(65535));
    Append(&expected, static_cast<uint32_t>(65536));
    Append(&expected, static_cast<uint64_t>(0xffffffffffffffff));
    Append(&expected, static_cast<uint8_t>(0));
    Append(&expected, static_cast<uint8_t>(0xff));

    EXPECT_TRUE(TestInputParser(input, true, expected, 0));
  }
  {
    std::string input = "[s8]-0x800 [s1]-128\t[s2]+0 [s4]-40";
    std::vector<uint8_t> expected;
    Append(&expected, -static_cast<int64_t>(0x800));
    Append(&expected, static_cast<int8_t>(-128));
    Append(&expected, static_cast<int16_t>(0));
    Append(&expected, static_cast<int32_t>(-40));

    EXPECT_TRUE(TestInputParser(input, true, expected, 0));
  }
  {
    std::string input = "[b]00001011 [b]10000000  // hello world\r [b]00000000";
    std::vector<uint8_t> expected;
    Append(&expected, static_cast<uint8_t>(11));
    Append(&expected, static_cast<uint8_t>(128));
    Append(&expected, static_cast<uint8_t>(0));

    EXPECT_TRUE(TestInputParser(input, true, expected, 0));
  }
  {
    std::string input = "[f]+.3e9 [d]-10.03";
    std::vector<uint8_t> expected;
    Append(&expected, +.3e9f);
    Append(&expected, -10.03);

    EXPECT_TRUE(TestInputParser(input, true, expected, 0));
  }
  {
    std::string input = "[dist4]foo 0 [dist8]bar 0 [anchr]foo [anchr]bar";
    std::vector<uint8_t> expected;
    Append(&expected, static_cast<uint32_t>(14));
    Append(&expected, static_cast<uint8_t>(0));
    Append(&expected, static_cast<uint64_t>(9));
    Append(&expected, static_cast<uint8_t>(0));

    EXPECT_TRUE(TestInputParser(input, true, expected, 0));
  }
  {
    std::string input = "// This message has handles! \n[handles]50 [u8]2";
    std::vector<uint8_t> expected;
    Append(&expected, static_cast<uint64_t>(2));

    EXPECT_TRUE(TestInputParser(input, true, expected, 50));
  }

  // Test some failure cases.
  {
    const char* error_inputs[] = {"/ hello world",
                                  "[u1]x",
                                  "[u2]-1000",
                                  "[u1]0x100",
                                  "[s2]-0x8001",
                                  "[b]1",
                                  "[b]1111111k",
                                  "[dist4]unmatched",
                                  "[anchr]hello [dist8]hello",
                                  "[dist4]a [dist4]a [anchr]a",
                                  "[dist4]a [anchr]a [dist4]a [anchr]a",
                                  "0 [handles]50",
                                  nullptr};

    for (size_t i = 0; error_inputs[i]; ++i) {
      std::vector<uint8_t> expected;
      if (!TestInputParser(error_inputs[i], false, expected, 0))
        ADD_FAILURE() << "Unexpected test result for: " << error_inputs[i];
    }
  }
}

TEST_F(ValidationTest, Conformance) {
  DummyMessageReceiver dummy_receiver;
  MessageValidatorList validators;
  validators.push_back(std::unique_ptr<MessageValidator>(
      new mojo::internal::MessageHeaderValidator));
  validators.push_back(std::unique_ptr<MessageValidator>(
      new ConformanceTestInterface::RequestValidator_));

  RunValidationTests("conformance_", validators, &dummy_receiver);
}

// This test is similar to Conformance test but its goal is specifically
// do bounds-check testing of message validation. For example we test the
// detection of off-by-one errors in method ordinals.
TEST_F(ValidationTest, BoundsCheck) {
  DummyMessageReceiver dummy_receiver;
  MessageValidatorList validators;
  validators.push_back(std::unique_ptr<MessageValidator>(
      new mojo::internal::MessageHeaderValidator));
  validators.push_back(std::unique_ptr<MessageValidator>(
      new BoundsCheckTestInterface::RequestValidator_));

  RunValidationTests("boundscheck_", validators, &dummy_receiver);
}

// This test is similar to the Conformance test but for responses.
TEST_F(ValidationTest, ResponseConformance) {
  DummyMessageReceiver dummy_receiver;
  MessageValidatorList validators;
  validators.push_back(std::unique_ptr<MessageValidator>(
      new mojo::internal::MessageHeaderValidator));
  validators.push_back(std::unique_ptr<MessageValidator>(
      new ConformanceTestInterface::ResponseValidator_));

  RunValidationTests("resp_conformance_", validators, &dummy_receiver);
}

// This test is similar to the BoundsCheck test but for responses.
TEST_F(ValidationTest, ResponseBoundsCheck) {
  DummyMessageReceiver dummy_receiver;
  MessageValidatorList validators;
  validators.push_back(std::unique_ptr<MessageValidator>(
      new mojo::internal::MessageHeaderValidator));
  validators.push_back(std::unique_ptr<MessageValidator>(
      new BoundsCheckTestInterface::ResponseValidator_));

  RunValidationTests("resp_boundscheck_", validators, &dummy_receiver);
}

// Test that InterfacePtr<X> applies the correct validators and they don't
// conflict with each other:
//   - MessageHeaderValidator
//   - X::ResponseValidator_
TEST_F(ValidationIntegrationTest, InterfacePtr) {
  IntegrationTestInterfacePtr interface_ptr =
      IntegrationTestInterfacePtr::Create(
          InterfaceHandle<IntegrationTestInterface>(testee_endpoint(), 0u));
  interface_ptr.internal_state()->router_for_testing()->EnableTestingMode();

  mojo::internal::MessageValidatorList validators;
  validators.push_back(std::unique_ptr<MessageValidator>(
      new mojo::internal::MessageHeaderValidator));
  validators.push_back(std::unique_ptr<MessageValidator>(
      new typename IntegrationTestInterface::ResponseValidator_));

  RunValidationTests("integration_intf_resp", validators,
                     test_message_receiver());
  RunValidationTests("integration_msghdr", validators, test_message_receiver());
}

// Test that Binding<X> applies the correct validators and they don't
// conflict with each other:
//   - MessageHeaderValidator
//   - X::RequestValidator_
TEST_F(ValidationIntegrationTest, Binding) {
  IntegrationTestInterfaceImpl interface_impl;
  Binding<IntegrationTestInterface> binding(
      &interface_impl,
      MakeRequest<IntegrationTestInterface>(testee_endpoint().Pass()));
  binding.internal_router()->EnableTestingMode();

  mojo::internal::MessageValidatorList validators;
  validators.push_back(std::unique_ptr<MessageValidator>(
      new mojo::internal::MessageHeaderValidator));
  validators.push_back(std::unique_ptr<MessageValidator>(
      new typename IntegrationTestInterface::RequestValidator_));

  RunValidationTests("integration_intf_rqst", validators,
                     test_message_receiver());
  RunValidationTests("integration_msghdr", validators, test_message_receiver());
}

// Test pointer validation (specifically, that the encoded offset is 32-bit)
TEST_F(ValidationTest, ValidateEncodedPointer) {
  uint64_t offset;

  offset = 0ULL;
  EXPECT_TRUE(mojo::internal::ValidateEncodedPointer(&offset));

  offset = 1ULL;
  EXPECT_TRUE(mojo::internal::ValidateEncodedPointer(&offset));

  // offset must be <= 32-bit.
  offset = std::numeric_limits<uint32_t>::max() + 1ULL;
  EXPECT_FALSE(mojo::internal::ValidateEncodedPointer(&offset));
}

TEST_F(ValidationTest, RunValidatorsOnMessageTest) {
  Message msg;
  mojo::internal::MessageValidatorList validators;

  validators.push_back(std::unique_ptr<MessageValidator>(
      new mojo::internal::PassThroughValidator));
  EXPECT_EQ(ValidationError::NONE,
            RunValidatorsOnMessage(validators, &msg, nullptr));

  validators.push_back(std::unique_ptr<MessageValidator>(
      new FailingValidator(ValidationError::MESSAGE_HEADER_INVALID_FLAGS)));
  EXPECT_EQ(ValidationError::MESSAGE_HEADER_INVALID_FLAGS,
            RunValidatorsOnMessage(validators, &msg, nullptr));

  validators.insert(validators.begin(),
                    std::unique_ptr<MessageValidator>(
                        new FailingValidator(ValidationError::ILLEGAL_HANDLE)));
  EXPECT_EQ(ValidationError::ILLEGAL_HANDLE,
            RunValidatorsOnMessage(validators, &msg, nullptr));
}

// Tests the IsValidValue() function generated for BasicEnum.
TEST(EnumValueValidationTest, BasicEnum) {
  // BasicEnum can have -3,0,1,10 as possible integral values.
  EXPECT_FALSE(BasicEnum_IsValidValue(static_cast<BasicEnum>(-4)));
  EXPECT_TRUE(BasicEnum_IsValidValue(static_cast<BasicEnum>(-3)));
  EXPECT_FALSE(BasicEnum_IsValidValue(static_cast<BasicEnum>(-2)));
  EXPECT_FALSE(BasicEnum_IsValidValue(static_cast<BasicEnum>(-1)));
  EXPECT_TRUE(BasicEnum_IsValidValue(static_cast<BasicEnum>(0)));
  EXPECT_TRUE(BasicEnum_IsValidValue(static_cast<BasicEnum>(1)));
  EXPECT_FALSE(BasicEnum_IsValidValue(static_cast<BasicEnum>(2)));
  EXPECT_FALSE(BasicEnum_IsValidValue(static_cast<BasicEnum>(9)));
  // In the mojom, we represent this value as hex (0xa).
  EXPECT_TRUE(BasicEnum_IsValidValue(static_cast<BasicEnum>(10)));
  EXPECT_FALSE(BasicEnum_IsValidValue(static_cast<BasicEnum>(11)));
}

// Tests the IsValidValue() method generated for StructWithEnum.
TEST(EnumValueValidationTest, EnumWithin) {
  // StructWithEnum::EnumWithin can have [0,4] as possible integral values.
  EXPECT_FALSE(StructWithEnum::EnumWithin_IsValidValue(
      static_cast<StructWithEnum::EnumWithin>(-1)));
  EXPECT_TRUE(StructWithEnum::EnumWithin_IsValidValue(
      static_cast<StructWithEnum::EnumWithin>(0)));
  EXPECT_TRUE(StructWithEnum::EnumWithin_IsValidValue(
      static_cast<StructWithEnum::EnumWithin>(1)));
  EXPECT_TRUE(StructWithEnum::EnumWithin_IsValidValue(
      static_cast<StructWithEnum::EnumWithin>(2)));
  EXPECT_TRUE(StructWithEnum::EnumWithin_IsValidValue(
      static_cast<StructWithEnum::EnumWithin>(3)));
  EXPECT_FALSE(StructWithEnum::EnumWithin_IsValidValue(
      static_cast<StructWithEnum::EnumWithin>(4)));
}

}  // namespace
}  // namespace test
}  // namespace mojo
