/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you 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 <vector>
#include <utility>
#include <sstream>

#include <ts/ts.h>

#include "swoc/TextView.h"

#include "tscpp/api/Continuation.h"

// TSReleaseAssert() doesn't seem to produce any logging output for a debug build, so do both kinds of assert.
//
#define ALWAYS_ASSERT(EXPR) \
  {                         \
    TSAssert(EXPR);         \
    TSReleaseAssert(EXPR);  \
  }

std::vector<void (*)()> testList;

struct ATest {
  ATest(void (*testFuncPtr)()) { testList.push_back(testFuncPtr); }
};

// Put a test function, whose name is the actual parameter for TEST_FUNC, into testList, the list of test functions.
//
#define TEST(TEST_FUNC) ATest t(TEST_FUNC);

// TextView test. This is not testing the actual TextView code, just that it works to call functions in TextView.cc in the core
// from a plugin.
//
namespace TextViewTest
{
void
f()
{
  swoc::TextView tv("abcdefg");

  std::ostringstream oss;

  oss << tv;

  ALWAYS_ASSERT(memcmp(swoc::TextView(oss.str()), tv) == 0)
}

TEST(f)

} // end namespace TextViewTest

// Test for Continuation class.
//
namespace ContinuationTest
{
struct {
  TSEvent event;
  void   *edata;
} passedToEventFunc;

bool
checkPassed(TSEvent event, void *edata)
{
  return (passedToEventFunc.event == event) and (passedToEventFunc.edata == edata);
}

class TestCont : public atscppapi::Continuation
{
public:
  TestCont(Mutex m) : atscppapi::Continuation(m) {}

  TestCont() = default;

private:
  int
  _run(TSEvent event, void *edata) override
  {
    passedToEventFunc.event = event;
    passedToEventFunc.edata = edata;

    return 666;
  }
};

void
f()
{
  TestCont::Mutex m(TSMutexCreate());

  TestCont c(m);

  ALWAYS_ASSERT(!!c)
  ALWAYS_ASSERT(c.asTSCont() != nullptr)
  ALWAYS_ASSERT(c.mutex() == m)

  TestCont c2(std::move(c));

  ALWAYS_ASSERT(!!c2)
  ALWAYS_ASSERT(c2.asTSCont() != nullptr)
  ALWAYS_ASSERT(c2.mutex() == m)

  // clang-analyzer warns about use-after-move for the following, but the
  // atscppapi::Continuation API is designed to support use after move and this
  // test intentionally exercises this behavior. Thus we disable clang-analyzer
  // for this code.
#if !defined(__clang_analyzer__) && !defined(__COVERITY__)
  ALWAYS_ASSERT(!c)
  ALWAYS_ASSERT(c.asTSCont() == nullptr)
  ALWAYS_ASSERT(c.mutex() == nullptr)
#endif

  TestCont c3;

  ALWAYS_ASSERT(!c3)
  ALWAYS_ASSERT(c3.asTSCont() == nullptr)
  ALWAYS_ASSERT(c3.mutex() == nullptr)

  c3 = std::move(c2);

  ALWAYS_ASSERT(!!c3)
  ALWAYS_ASSERT(c3.asTSCont() != nullptr)
  ALWAYS_ASSERT(c3.mutex() == m)

  // See the user-after-move comment above for the reason we disable
  // clang-analyzer here.
#ifndef __clang_analyzer__
  ALWAYS_ASSERT(!c2)
  ALWAYS_ASSERT(c2.asTSCont() == nullptr)
  ALWAYS_ASSERT(c2.mutex() == nullptr)
#endif

  c3.destroy();

  ALWAYS_ASSERT(!c3)
  ALWAYS_ASSERT(c3.asTSCont() == nullptr)
  ALWAYS_ASSERT(c3.mutex() == nullptr)

  c = TestCont(m);

  ALWAYS_ASSERT(!!c)
  ALWAYS_ASSERT(c.asTSCont() != nullptr)
  ALWAYS_ASSERT(c.mutex() == m)
}

TEST(f)

} // end namespace ContinuationTest

// Run all the tests.
//
void
TSPluginInit(int, const char **)
{
  TSPluginRegistrationInfo info;

  info.plugin_name   = "test_cppapi";
  info.vendor_name   = "Apache Software Foundation";
  info.support_email = "dev@trafficserver.apache.org";

  ALWAYS_ASSERT(TSPluginRegister(&info) == TS_SUCCESS)

  for (auto fp : testList) {
    fp();
  }
}
