/* Copyright 2017 The BoringSSL Authors
 *
 * Permission to use, copy, modify, and/or distribute this software for any
 * purpose with or without fee is hereby granted, provided that the above
 * copyright notice and this permission notice appear in all copies.
 *
 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
 * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
 * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */

#include "file_test.h"

#include <assert.h>
#include <string.h>

#include <memory>
#include <string>
#include <utility>

#include <gtest/gtest.h>

#include <openssl/err.h>

#include "test_data.h"


class StringLineReader : public FileTest::LineReader {
 public:
  explicit StringLineReader(const std::string &data)
      : data_(data), offset_(0) {}

  FileTest::ReadResult ReadLine(char *out, size_t len) override {
    assert(len > 0);
    if (offset_ == data_.size()) {
      return FileTest::kReadEOF;
    }

    size_t idx = data_.find('\n', offset_);
    if (idx == std::string::npos) {
      idx = data_.size();
    } else {
      idx++;  // Include the newline.
    }

    if (idx - offset_ > len - 1) {
      ADD_FAILURE() << "Line too long.";
      return FileTest::kReadError;
    }

    memcpy(out, data_.data() + offset_, idx - offset_);
    out[idx - offset_] = '\0';
    offset_ = idx;
    return FileTest::kReadSuccess;
  }

 private:
  std::string data_;
  size_t offset_;

  StringLineReader(const StringLineReader &) = delete;
  StringLineReader &operator=(const StringLineReader &) = delete;
};

void FileTestGTest(const char *path, std::function<void(FileTest *)> run_test) {
  FileTest t(std::make_unique<StringLineReader>(GetTestData(path)), nullptr,
             false);

  while (true) {
    switch (t.ReadNext()) {
      case FileTest::kReadError:
        ADD_FAILURE() << "Error reading test.";
        return;
      case FileTest::kReadEOF:
        return;
      case FileTest::kReadSuccess:
        break;
    }

    const testing::TestResult *test_result =
        testing::UnitTest::GetInstance()->current_test_info()->result();
    int before_part_count = test_result->total_part_count();

    SCOPED_TRACE(testing::Message() << path << ", line " << t.start_line());
    run_test(&t);

    // Check for failures from the most recent test.
    bool failed = false;
    for (int i = before_part_count; i < test_result->total_part_count(); i++) {
      if (test_result->GetTestPartResult(i).failed()) {
        failed = true;
        break;
      }
    }

    // Clean up the error queue for the next test, reporting it on failure.
    if (failed) {
      ERR_print_errors_fp(stdout);
    } else {
      ERR_clear_error();
    }
  }
}
