/*
 * Copyright (C) 2017 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 <gtest/gtest.h>
#include "src/logd/LogEvent.h"
#include "frameworks/base/cmds/statsd/src/statsd_config.pb.h"
#include "matchers/matcher_util.h"
#include "stats_log_util.h"
#include "stats_util.h"
#include "subscriber/SubscriberReporter.h"

#ifdef __ANDROID__

namespace android {
namespace os {
namespace statsd {

TEST(AtomMatcherTest, TestFieldTranslation) {
    FieldMatcher matcher1;
    matcher1.set_field(10);
    FieldMatcher* child = matcher1.add_child();
    child->set_field(1);
    child->set_position(Position::ANY);

    child = child->add_child();
    child->set_field(1);

    vector<Matcher> output;
    translateFieldMatcher(matcher1, &output);

    EXPECT_EQ((size_t)1, output.size());

    const auto& matcher12 = output[0];
    EXPECT_EQ((int32_t)10, matcher12.mMatcher.getTag());
    EXPECT_EQ((int32_t)0x2010001, matcher12.mMatcher.getField());
    EXPECT_EQ((int32_t)0xff7f007f, matcher12.mMask);
}

TEST(AtomMatcherTest, TestFilter) {
    FieldMatcher matcher1;
    matcher1.set_field(10);
    FieldMatcher* child = matcher1.add_child();
    child->set_field(1);
    child->set_position(Position::ANY);

    child = child->add_child();
    child->set_field(1);

    child = matcher1.add_child();
    child->set_field(2);

    vector<Matcher> matchers;
    translateFieldMatcher(matcher1, &matchers);

    AttributionNode attribution_node1;
    attribution_node1.set_uid(1111);
    attribution_node1.set_tag("location1");

    AttributionNode attribution_node2;
    attribution_node2.set_uid(2222);
    attribution_node2.set_tag("location2");

    AttributionNode attribution_node3;
    attribution_node3.set_uid(3333);
    attribution_node3.set_tag("location3");
    std::vector<AttributionNode> attribution_nodes = {attribution_node1, attribution_node2,
                                                      attribution_node3};

    // Set up the event
    LogEvent event(10, 12345);
    event.write(attribution_nodes);
    event.write("some value");
    // Convert to a LogEvent
    event.init();
    vector<HashableDimensionKey> output;

    filterValues(matchers, event.getValues(), &output);

    EXPECT_EQ((size_t)(3), output.size());

    const auto& key1 = output[0];
    EXPECT_EQ((size_t)2, key1.getValues().size());
    EXPECT_EQ((int32_t)0x02010001, key1.getValues()[0].mField.getField());
    EXPECT_EQ((int32_t)1111, key1.getValues()[0].mValue.int_value);
    EXPECT_EQ((int32_t)0x00020000, key1.getValues()[1].mField.getField());
    EXPECT_EQ("some value", key1.getValues()[1].mValue.str_value);

    const auto& key2 = output[1];
    EXPECT_EQ((size_t)2, key2.getValues().size());
    EXPECT_EQ((int32_t)0x02010001, key2.getValues()[0].mField.getField());
    EXPECT_EQ((int32_t)2222, key2.getValues()[0].mValue.int_value);
    EXPECT_EQ((int32_t)0x00020000, key2.getValues()[1].mField.getField());
    EXPECT_EQ("some value", key2.getValues()[1].mValue.str_value);

    const auto& key3 = output[2];
    EXPECT_EQ((size_t)2, key3.getValues().size());
    EXPECT_EQ((int32_t)0x02010001, key3.getValues()[0].mField.getField());
    EXPECT_EQ((int32_t)3333, key3.getValues()[0].mValue.int_value);
    EXPECT_EQ((int32_t)0x00020000, key3.getValues()[1].mField.getField());
    EXPECT_EQ("some value", key3.getValues()[1].mValue.str_value);
}

TEST(AtomMatcherTest, TestSubDimension) {
    HashableDimensionKey dim;

    int pos1[] = {1, 1, 1};
    int pos2[] = {1, 1, 2};
    int pos3[] = {1, 1, 3};
    int pos4[] = {2, 0, 0};
    Field field1(10, pos1, 2);
    Field field2(10, pos2, 2);

    Field field3(10, pos3, 2);
    Field field4(10, pos4, 0);

    Value value1((int32_t)10025);
    Value value2("tag");

    Value value11((int32_t)10026);
    Value value22("tag2");

    dim.addValue(FieldValue(field1, value1));
    dim.addValue(FieldValue(field2, value2));

    HashableDimensionKey subDim1;
    subDim1.addValue(FieldValue(field1, value1));

    HashableDimensionKey subDim2;
    subDim1.addValue(FieldValue(field2, value2));

    EXPECT_TRUE(dim.contains(dim));
    EXPECT_TRUE(dim.contains(subDim1));
    EXPECT_TRUE(dim.contains(subDim2));

    HashableDimensionKey subDim3;
    subDim3.addValue(FieldValue(field1, value11));
    EXPECT_FALSE(dim.contains(subDim3));

    HashableDimensionKey subDim4;
    // Empty dimension is always a sub dimension of other dimensions
    EXPECT_TRUE(dim.contains(subDim4));
}

TEST(AtomMatcherTest, TestMetric2ConditionLink) {
    AttributionNode attribution_node1;
    attribution_node1.set_uid(1111);
    attribution_node1.set_tag("location1");

    AttributionNode attribution_node2;
    attribution_node2.set_uid(2222);
    attribution_node2.set_tag("location2");

    AttributionNode attribution_node3;
    attribution_node3.set_uid(3333);
    attribution_node3.set_tag("location3");
    std::vector<AttributionNode> attribution_nodes = {attribution_node1, attribution_node2,
                                                      attribution_node3};

    // Set up the event
    LogEvent event(10, 12345);
    event.write(attribution_nodes);
    event.write("some value");
    // Convert to a LogEvent
    event.init();

    FieldMatcher whatMatcher;
    whatMatcher.set_field(10);
    FieldMatcher* child11 = whatMatcher.add_child();
    child11->set_field(1);
    child11->set_position(Position::ANY);
    child11 = child11->add_child();
    child11->set_field(1);

    FieldMatcher conditionMatcher;
    conditionMatcher.set_field(27);
    FieldMatcher* child2 = conditionMatcher.add_child();
    child2->set_field(2);
    child2->set_position(Position::LAST);

    child2 = child2->add_child();
    child2->set_field(2);

    Metric2Condition link;

    translateFieldMatcher(whatMatcher, &link.metricFields);
    translateFieldMatcher(conditionMatcher, &link.conditionFields);

    EXPECT_EQ((size_t)1, link.metricFields.size());
    EXPECT_EQ((int32_t)0x02010001, link.metricFields[0].mMatcher.getField());
    EXPECT_EQ((int32_t)0xff7f007f, link.metricFields[0].mMask);
    EXPECT_EQ((int32_t)10, link.metricFields[0].mMatcher.getTag());

    EXPECT_EQ((size_t)1, link.conditionFields.size());
    EXPECT_EQ((int32_t)0x02028002, link.conditionFields[0].mMatcher.getField());
    EXPECT_EQ((int32_t)0xff7f807f, link.conditionFields[0].mMask);
    EXPECT_EQ((int32_t)27, link.conditionFields[0].mMatcher.getTag());
}

TEST(AtomMatcherTest, TestSubscriberDimensionWrite) {
    HashableDimensionKey dim;

    int pos1[] = {1, 1, 1};
    int pos2[] = {1, 1, 2};
    int pos3[] = {1, 1, 3};
    int pos4[] = {2, 0, 0};

    Field field1(10, pos1, 2);
    Field field2(10, pos2, 2);
    Field field3(10, pos3, 2);
    Field field4(10, pos4, 0);

    Value value1((int32_t)10025);
    Value value2("tag");
    Value value3((int32_t)987654);
    Value value4((int32_t)99999);

    dim.addValue(FieldValue(field1, value1));
    dim.addValue(FieldValue(field2, value2));
    dim.addValue(FieldValue(field3, value3));
    dim.addValue(FieldValue(field4, value4));

    SubscriberReporter::getStatsDimensionsValue(dim);
    // TODO: can't test anything here because SubscriberReport class doesn't have any read api.
}

TEST(AtomMatcherTest, TestWriteDimensionToProto) {
    HashableDimensionKey dim;
    int pos1[] = {1, 1, 1};
    int pos2[] = {1, 1, 2};
    int pos3[] = {1, 1, 3};
    int pos4[] = {2, 0, 0};
    Field field1(10, pos1, 2);
    Field field2(10, pos2, 2);
    Field field3(10, pos3, 2);
    Field field4(10, pos4, 0);

    Value value1((int32_t)10025);
    Value value2("tag");
    Value value3((int32_t)987654);
    Value value4((int32_t)99999);

    dim.addValue(FieldValue(field1, value1));
    dim.addValue(FieldValue(field2, value2));
    dim.addValue(FieldValue(field3, value3));
    dim.addValue(FieldValue(field4, value4));

    android::util::ProtoOutputStream protoOut;
    writeDimensionToProto(dim, &protoOut);

    vector<uint8_t> outData;
    outData.resize(protoOut.size());
    size_t pos = 0;
    auto iter = protoOut.data();
    while (iter.readBuffer() != NULL) {
        size_t toRead = iter.currentToRead();
        std::memcpy(&(outData[pos]), iter.readBuffer(), toRead);
        pos += toRead;
        iter.rp()->move(toRead);
    }

    DimensionsValue result;
    EXPECT_EQ(true, result.ParseFromArray(&outData[0], outData.size()));
    EXPECT_EQ(10, result.field());
    EXPECT_EQ(DimensionsValue::ValueCase::kValueTuple, result.value_case());
    EXPECT_EQ(2, result.value_tuple().dimensions_value_size());

    const auto& dim1 = result.value_tuple().dimensions_value(0);
    EXPECT_EQ(DimensionsValue::ValueCase::kValueTuple, dim1.value_case());
    EXPECT_EQ(3, dim1.value_tuple().dimensions_value_size());

    const auto& dim11 = dim1.value_tuple().dimensions_value(0);
    EXPECT_EQ(DimensionsValue::ValueCase::kValueInt, dim11.value_case());
    EXPECT_EQ(10025, dim11.value_int());

    const auto& dim12 = dim1.value_tuple().dimensions_value(1);
    EXPECT_EQ(DimensionsValue::ValueCase::kValueStr, dim12.value_case());
    EXPECT_EQ("tag", dim12.value_str());

    const auto& dim13 = dim1.value_tuple().dimensions_value(2);
    EXPECT_EQ(DimensionsValue::ValueCase::kValueInt, dim13.value_case());
    EXPECT_EQ(987654, dim13.value_int());

    const auto& dim2 = result.value_tuple().dimensions_value(1);
    EXPECT_EQ(DimensionsValue::ValueCase::kValueInt, dim2.value_case());
    EXPECT_EQ(99999, dim2.value_int());
}

TEST(AtomMatcherTest, TestWriteAtomToProto) {
    AttributionNode attribution_node1;
    attribution_node1.set_uid(1111);
    attribution_node1.set_tag("location1");

    AttributionNode attribution_node2;
    attribution_node2.set_uid(2222);
    attribution_node2.set_tag("location2");

    std::vector<AttributionNode> attribution_nodes = {attribution_node1, attribution_node2};

    // Set up the event
    LogEvent event(4, 12345);
    event.write(attribution_nodes);
    event.write((int32_t)999);
    // Convert to a LogEvent
    event.init();

    android::util::ProtoOutputStream protoOutput;
    writeFieldValueTreeToStream(event.GetTagId(), event.getValues(), &protoOutput);

    vector<uint8_t> outData;
    outData.resize(protoOutput.size());
    size_t pos = 0;
    auto iter = protoOutput.data();
    while (iter.readBuffer() != NULL) {
        size_t toRead = iter.currentToRead();
        std::memcpy(&(outData[pos]), iter.readBuffer(), toRead);
        pos += toRead;
        iter.rp()->move(toRead);
    }

    Atom result;
    EXPECT_EQ(true, result.ParseFromArray(&outData[0], outData.size()));
    EXPECT_EQ(Atom::PushedCase::kBleScanResultReceived, result.pushed_case());
    const auto& atom = result.ble_scan_result_received();
    EXPECT_EQ(2, atom.attribution_node_size());
    EXPECT_EQ(1111, atom.attribution_node(0).uid());
    EXPECT_EQ("location1", atom.attribution_node(0).tag());
    EXPECT_EQ(2222, atom.attribution_node(1).uid());
    EXPECT_EQ("location2", atom.attribution_node(1).tag());
    EXPECT_EQ(999, atom.num_of_results());
}


}  // namespace statsd
}  // namespace os
}  // namespace android
#else
GTEST_LOG_(INFO) << "This test does nothing.\n";
#endif