/*
 * Copyright (C) 2021 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.
 */

#pragma once

#include <unordered_map>
#include <vector>

#include <android-modules-utils/sdk_level.h>
#include <gtest/gtest_prod.h>
#include <server_configurable_flags/get_flags.h>

#include <mutex>
#include <string>

namespace android {
namespace os {
namespace statsd {

using GetServerFlagFunc =
        std::function<std::string(const std::string&, const std::string&, const std::string&)>;
using IsAtLeastSFunc = std::function<bool()>;

const std::string STATSD_NATIVE_NAMESPACE = "statsd_native";
const std::string STATSD_NATIVE_BOOT_NAMESPACE = "statsd_native_boot";

const std::string VALUE_METRIC_SUBSET_DIMENSION_AGGREGATION_FLAG =
        "value_metric_subset_dimension_aggregation";

const std::string FLAG_TRUE = "true";
const std::string FLAG_FALSE = "false";
const std::string FLAG_EMPTY = "";

class FlagProvider {
public:
    static FlagProvider& getInstance();

    std::string getFlagString(const std::string& flagName, const std::string& defaultValue) const;

    // Returns true IFF flagName has a value of "true".
    bool getFlagBool(const std::string& flagName, const std::string& defaultValue) const;

    std::string getBootFlagString(const std::string& flagName,
                                  const std::string& defaultValue) const;

    // Returns true IFF flagName has a value of "true".
    bool getBootFlagBool(const std::string& flagName, const std::string& defaultValue) const;

    // Queries the boot flags. Should only be called once at boot.
    void initBootFlags(const std::vector<std::string>& flags);

private:
    FlagProvider();

    // TODO(b/194347008): Remove the GetServerConfigurableFlag override.
    void overrideFuncs(
            const IsAtLeastSFunc& isAtLeastSFunc = &android::modules::sdklevel::IsAtLeastS,
            const GetServerFlagFunc& getServerFlagFunc =
                    &server_configurable_flags::GetServerConfigurableFlag);

    void overrideFuncsLocked(
            const IsAtLeastSFunc& isAtLeastSFunc = &android::modules::sdklevel::IsAtLeastS,
            const GetServerFlagFunc& getServerFlagFunc =
                    &server_configurable_flags::GetServerConfigurableFlag);

    inline void resetOverrides() {
        std::lock_guard<std::mutex> lock(mFlagsMutex);
        overrideFuncsLocked();
        mLocalFlags.clear();
    }

    void overrideFlag(const std::string& flagName, const std::string& flagValue,
                      const bool isBootFlag = false);

    std::string getFlagStringInternal(const std::string& flagName, const std::string& flagValue,
                                      const bool isBootFlag) const;

    std::string getLocalFlagKey(const std::string& flagName, const bool isBootFlag = false) const;

    IsAtLeastSFunc mIsAtLeastSFunc;
    GetServerFlagFunc mGetServerFlagFunc;

    // Flag values updated only at boot. Used to store boot flags.
    std::unordered_map<std::string, std::string> mBootFlags;

    // Flag values to be locally overwritten. Only used in tests.
    std::unordered_map<std::string, std::string> mLocalFlags;

    mutable std::mutex mFlagsMutex;

    friend class ConfigUpdateE2eTest;
    friend class ConfigUpdateTest;
    friend class EventMetricE2eTest;
    friend class GaugeMetricE2ePulledTest;
    friend class GaugeMetricE2ePushedTest;
    friend class EventMetricProducerTest;
    friend class FlagProviderTest_RMinus;
    friend class FlagProviderTest_SPlus;
    friend class FlagProviderTest_SPlus_RealValues;
    friend class KllMetricE2eAbTest;
    friend class MetricsManagerTest;
    friend class NumericValueMetricProducerTest_SubsetDimensions;
    friend class PartialBucketE2e_AppUpgradeDefaultTest;

    FRIEND_TEST(ConfigUpdateE2eTest, TestKllMetric_KllDisabledBeforeConfigUpdate);
    FRIEND_TEST(ConfigUpdateE2eTest, TestEventMetric);
    FRIEND_TEST(ConfigUpdateE2eTest, TestGaugeMetric);
    FRIEND_TEST(EventMetricE2eTest, TestEventMetricDataAggregated);
    FRIEND_TEST(EventMetricProducerTest, TestOneAtomTagAggregatedEvents);
    FRIEND_TEST(EventMetricProducerTest, TestTwoAtomTagAggregatedEvents);
    FRIEND_TEST(GaugeMetricE2ePulledTest, TestRandomSamplePulledEventsNoCondition);
    FRIEND_TEST(FlagProviderTest_SPlus, TestGetFlagBoolServerFlagTrue);
    FRIEND_TEST(FlagProviderTest_SPlus, TestGetFlagBoolServerFlagFalse);
    FRIEND_TEST(FlagProviderTest_SPlus, TestOverrideLocalFlags);
    FRIEND_TEST(FlagProviderTest_SPlus, TestGetFlagBoolServerFlagEmptyDefaultFalse);
    FRIEND_TEST(FlagProviderTest_SPlus, TestGetFlagBoolServerFlagEmptyDefaultTrue);
    FRIEND_TEST(FlagProviderTest_SPlus_RealValues, TestGetBootFlagBoolServerFlagTrue);
    FRIEND_TEST(FlagProviderTest_SPlus_RealValues, TestGetBootFlagBoolServerFlagFalse);
    FRIEND_TEST(NumericValueMetricProducerTest_SubsetDimensions, TestSubsetDimensions_FlagTrue);
    FRIEND_TEST(NumericValueMetricProducerTest_SubsetDimensions, TestSubsetDimensions_FlagFalse);
    FRIEND_TEST(PartialBucketE2e_AppUpgradeDefaultTest, TestCountMetricDefaultFalse);
    FRIEND_TEST(PartialBucketE2e_AppUpgradeDefaultTest, TestCountMetricDefaultTrue);
};

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