// 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 "StatsLogProcessor.h"
#include "config/ConfigKey.h"
#include "frameworks/base/cmds/statsd/src/statsd_config.pb.h"
#include "guardrail/StatsdStats.h"
#include "logd/LogEvent.h"
#include "packages/UidMap.h"
#include "statslog.h"

#include <gmock/gmock.h>
#include <gtest/gtest.h>

#include <stdio.h>

using namespace android;
using namespace testing;

namespace android {
namespace os {
namespace statsd {

using android::util::ProtoOutputStream;

#ifdef __ANDROID__

/**
 * Mock MetricsManager (ByteSize() is called).
 */
class MockMetricsManager : public MetricsManager {
public:
    MockMetricsManager() : MetricsManager(ConfigKey(1, "key"), StatsdConfig(), 1000, new UidMap()) {
    }

    MOCK_METHOD0(byteSize, size_t());
    MOCK_METHOD1(onDumpReport, void(ProtoOutputStream* output));
};

TEST(StatsLogProcessorTest, TestRateLimitByteSize) {
    sp<UidMap> m = new UidMap();
    sp<AnomalyMonitor> anomalyMonitor;
    // Construct the processor with a dummy sendBroadcast function that does nothing.
    StatsLogProcessor p(m, anomalyMonitor, 0, [](const ConfigKey& key) {});

    MockMetricsManager mockMetricsManager;

    ConfigKey key(100, "key");
    // Expect only the first flush to trigger a check for byte size since the last two are
    // rate-limited.
    EXPECT_CALL(mockMetricsManager, byteSize()).Times(1);
    p.flushIfNecessary(99, key, mockMetricsManager);
    p.flushIfNecessary(100, key, mockMetricsManager);
    p.flushIfNecessary(101, key, mockMetricsManager);
}

TEST(StatsLogProcessorTest, TestRateLimitBroadcast) {
    sp<UidMap> m = new UidMap();
    sp<AnomalyMonitor> anomalyMonitor;
    int broadcastCount = 0;
    StatsLogProcessor p(m, anomalyMonitor, 0,
                        [&broadcastCount](const ConfigKey& key) { broadcastCount++; });

    MockMetricsManager mockMetricsManager;

    ConfigKey key(100, "key");
    EXPECT_CALL(mockMetricsManager, byteSize())
            .Times(2)
            .WillRepeatedly(Return(int(StatsdStats::kMaxMetricsBytesPerConfig * .95)));

    // Expect only one broadcast despite always returning a size that should trigger broadcast.
    p.flushIfNecessary(1, key, mockMetricsManager);
    EXPECT_EQ(1, broadcastCount);

    // This next call to flush should not trigger a broadcast.
    p.mLastByteSizeTimes.clear();  // Force another check for byte size.
    p.flushIfNecessary(2, key, mockMetricsManager);
    EXPECT_EQ(1, broadcastCount);
}

TEST(StatsLogProcessorTest, TestDropWhenByteSizeTooLarge) {
    sp<UidMap> m = new UidMap();
    sp<AnomalyMonitor> anomalyMonitor;
    int broadcastCount = 0;
    StatsLogProcessor p(m, anomalyMonitor, 0,
                        [&broadcastCount](const ConfigKey& key) { broadcastCount++; });

    MockMetricsManager mockMetricsManager;

    ConfigKey key(100, "key");
    EXPECT_CALL(mockMetricsManager, byteSize())
            .Times(1)
            .WillRepeatedly(Return(int(StatsdStats::kMaxMetricsBytesPerConfig * 1.2)));

    EXPECT_CALL(mockMetricsManager, onDumpReport(_)).Times(1);

    // Expect to call the onDumpReport and skip the broadcast.
    p.flushIfNecessary(1, key, mockMetricsManager);
    EXPECT_EQ(0, broadcastCount);
}

#else
GTEST_LOG_(INFO) << "This test does nothing.\n";
#endif

}  // namespace statsd
}  // namespace os
}  // namespace android
