/**
 * 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.
 */

#define __STDC_FORMAT_MACROS

#include "core/htrace.hpp"

extern "C" {
#include "core/conf.h"
#include "core/span.h"
#include "test/rtest.h"
#include "test/span_table.h"
#include "test/span_util.h"
#include "test/test.h"
#include "util/log.h"

#include <errno.h>
#include <inttypes.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
}

/**
 * @file rtestpp.cc
 *
 * The C++ receiver tests.
 */

using std::string;

class RTestData {
public:
    RTestData(struct rtest *rt, const char *conf_str)
        : rt_(rt),
          cnf_(string(HTRACE_PROCESS_ID"=%{tname}/%{pid};sampler=always;") +
               string(conf_str).c_str()),
          tracer_(RECEIVER_TEST_TNAME, cnf_),
          always_(&tracer_, cnf_)
    {
    }

    // Test that initialization succeeeded
    int TestInit() {
        EXPECT_STR_EQ(RECEIVER_TEST_TNAME, tracer_.Name().c_str());
        EXPECT_STR_EQ("AlwaysSampler", always_.ToString().c_str());
        return EXIT_SUCCESS;
    }

    struct rtest *rt_;
    htrace::Conf cnf_;
    htrace::Tracer tracer_;
    htrace::Sampler always_;

private:
    RTestData(const RTestData &other); // disallow copying
    RTestData& operator=(const RTestData &other); // disallow assignment
};

static void get_receiver_test_prid(char *prid, size_t prid_len)
{
    snprintf(prid, prid_len, RECEIVER_TEST_TNAME "/%lld", (long long)getpid());
}

static int rtest_generic_verify(struct rtest *rt, struct span_table *st)
{
    EXPECT_INT_EQ(rt->spans_created, span_table_size(st));

    return EXIT_SUCCESS;
}

static int doit(RTestData &tdata, struct rtest *rt)
{
    {
        htrace::Scope scope1(tdata.tracer_, "part1");
        EXPECT_UINT64_GT(0L, scope1.GetSpanId());
    }
    {
        htrace::Scope scope2(tdata.tracer_, "part2");
        EXPECT_UINT64_GT(0L, scope2.GetSpanId());
        {
            htrace::Scope scope2_5(tdata.tracer_, "part2.5");
            EXPECT_UINT64_GT(0L, scope2_5.GetSpanId());
        }
    }
    return EXIT_SUCCESS;
}

int rtestpp_simple_run(struct rtest *rt, const char *conf_str)
{
    RTestData tdata(rt, conf_str);
    EXPECT_INT_ZERO(tdata.TestInit());

    htrace::Scope scope0(tdata.tracer_, tdata.always_, "doit");
    doit(tdata, rt);
    rt->spans_created = 4;
    return EXIT_SUCCESS;
}

int rtestpp_simple_verify(struct rtest *rt, struct span_table *st)
{
    struct htrace_span *span;
    uint64_t doit_id, part2_id;
    char prid[128];

    EXPECT_INT_ZERO(rtest_generic_verify(rt, st));
    get_receiver_test_prid(prid, sizeof(prid));
    EXPECT_INT_ZERO(span_table_get(st, &span, "doit", prid));
    doit_id = span->span_id;
    EXPECT_INT_ZERO(span->num_parents);

    EXPECT_INT_ZERO(span_table_get(st, &span, "part1", prid));
    EXPECT_INT_EQ(1, span->num_parents);
    EXPECT_UINT64_EQ(doit_id, span->parent.single);

    EXPECT_INT_ZERO(span_table_get(st, &span, "part2", prid));
    EXPECT_INT_EQ(1, span->num_parents);
    part2_id = span->span_id;
    EXPECT_UINT64_EQ(doit_id, span->parent.single);

    EXPECT_INT_ZERO(span_table_get(st, &span, "part2.5", prid));
    EXPECT_INT_EQ(1, span->num_parents);
    EXPECT_UINT64_EQ(part2_id, span->parent.single);

    return EXIT_SUCCESS;
}

struct rtest g_rtestpp_simple = {
    "rtestpp_simple",
    rtestpp_simple_run,
    rtestpp_simple_verify,
};

struct rtest * const g_rtests[] = {
    &g_rtestpp_simple,
    NULL
};

// vim: ts=4:sw=4:tw=79:et
