/*
 * Copyright (C) 2014 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 <androidfw/ResourceTypes.h>
#include <utils/Log.h>
#include <utils/String8.h>
#include <utils/Vector.h>

#include "TestHelpers.h"
#include <gtest/gtest.h>

namespace android {

static ResTable_config selectBest(const ResTable_config& target,
        const Vector<ResTable_config>& configs) {
    ResTable_config bestConfig;
    memset(&bestConfig, 0, sizeof(bestConfig));
    const size_t configCount = configs.size();
    for (size_t i = 0; i < configCount; i++) {
        const ResTable_config& thisConfig = configs[i];
        if (!thisConfig.match(target)) {
            continue;
        }

        if (thisConfig.isBetterThan(bestConfig, &target)) {
            bestConfig = thisConfig;
        }
    }
    return bestConfig;
}

static ResTable_config buildDensityConfig(int density) {
    ResTable_config config;
    memset(&config, 0, sizeof(config));
    config.density = uint16_t(density);
    config.sdkVersion = 4;
    return config;
}

TEST(ConfigTest, shouldSelectBestDensity) {
    ResTable_config deviceConfig;
    memset(&deviceConfig, 0, sizeof(deviceConfig));
    deviceConfig.density = ResTable_config::DENSITY_XHIGH;
    deviceConfig.sdkVersion = 21;

    Vector<ResTable_config> configs;

    ResTable_config expectedBest = buildDensityConfig(ResTable_config::DENSITY_HIGH);
    configs.add(expectedBest);
    ASSERT_EQ(expectedBest, selectBest(deviceConfig, configs));

    expectedBest = buildDensityConfig(ResTable_config::DENSITY_XXHIGH);
    configs.add(expectedBest);
    ASSERT_EQ(expectedBest, selectBest(deviceConfig, configs));

    expectedBest = buildDensityConfig(int(ResTable_config::DENSITY_XXHIGH) - 20);
    configs.add(expectedBest);
    ASSERT_EQ(expectedBest, selectBest(deviceConfig, configs));

    configs.add(buildDensityConfig(int(ResTable_config::DENSITY_HIGH) + 20));
    ASSERT_EQ(expectedBest, selectBest(deviceConfig, configs));

    expectedBest = buildDensityConfig(ResTable_config::DENSITY_XHIGH);
    configs.add(expectedBest);
    ASSERT_EQ(expectedBest, selectBest(deviceConfig, configs));

    expectedBest = buildDensityConfig(ResTable_config::DENSITY_ANY);
    expectedBest.sdkVersion = 21;
    configs.add(expectedBest);
    ASSERT_EQ(expectedBest, selectBest(deviceConfig, configs));
}

TEST(ConfigTest, shouldSelectBestDensityWhenNoneSpecified) {
    ResTable_config deviceConfig;
    memset(&deviceConfig, 0, sizeof(deviceConfig));
    deviceConfig.sdkVersion = 21;

    Vector<ResTable_config> configs;
    configs.add(buildDensityConfig(ResTable_config::DENSITY_HIGH));

    ResTable_config expectedBest = buildDensityConfig(ResTable_config::DENSITY_MEDIUM);
    configs.add(expectedBest);
    ASSERT_EQ(expectedBest, selectBest(deviceConfig, configs));

    expectedBest = buildDensityConfig(ResTable_config::DENSITY_ANY);
    configs.add(expectedBest);
    ASSERT_EQ(expectedBest, selectBest(deviceConfig, configs));
}

TEST(ConfigTest, shouldMatchRoundQualifier) {
    ResTable_config deviceConfig;
    memset(&deviceConfig, 0, sizeof(deviceConfig));

    ResTable_config roundConfig;
    memset(&roundConfig, 0, sizeof(roundConfig));
    roundConfig.screenLayout2 = ResTable_config::SCREENROUND_YES;

    EXPECT_FALSE(roundConfig.match(deviceConfig));

    deviceConfig.screenLayout2 = ResTable_config::SCREENROUND_YES;

    EXPECT_TRUE(roundConfig.match(deviceConfig));

    deviceConfig.screenLayout2 = ResTable_config::SCREENROUND_NO;

    EXPECT_FALSE(roundConfig.match(deviceConfig));

    ResTable_config notRoundConfig;
    memset(&notRoundConfig, 0, sizeof(notRoundConfig));
    notRoundConfig.screenLayout2 = ResTable_config::SCREENROUND_NO;

    EXPECT_TRUE(notRoundConfig.match(deviceConfig));
}

TEST(ConfigTest, RoundQualifierShouldHaveStableSortOrder) {
    ResTable_config defaultConfig;
    memset(&defaultConfig, 0, sizeof(defaultConfig));

    ResTable_config longConfig = defaultConfig;
    longConfig.screenLayout = ResTable_config::SCREENLONG_YES;

    ResTable_config longRoundConfig = longConfig;
    longRoundConfig.screenLayout2 = ResTable_config::SCREENROUND_YES;

    ResTable_config longRoundPortConfig = longConfig;
    longRoundPortConfig.orientation = ResTable_config::ORIENTATION_PORT;

    EXPECT_TRUE(longConfig.compare(longRoundConfig) < 0);
    EXPECT_TRUE(longConfig.compareLogical(longRoundConfig) < 0);
    EXPECT_TRUE(longRoundConfig.compare(longConfig) > 0);
    EXPECT_TRUE(longRoundConfig.compareLogical(longConfig) > 0);

    EXPECT_TRUE(longRoundConfig.compare(longRoundPortConfig) < 0);
    EXPECT_TRUE(longRoundConfig.compareLogical(longRoundPortConfig) < 0);
    EXPECT_TRUE(longRoundPortConfig.compare(longRoundConfig) > 0);
    EXPECT_TRUE(longRoundPortConfig.compareLogical(longRoundConfig) > 0);
}

TEST(ConfigTest, ScreenShapeHasCorrectDiff) {
    ResTable_config defaultConfig;
    memset(&defaultConfig, 0, sizeof(defaultConfig));

    ResTable_config roundConfig = defaultConfig;
    roundConfig.screenLayout2 = ResTable_config::SCREENROUND_YES;

    EXPECT_EQ(defaultConfig.diff(roundConfig), ResTable_config::CONFIG_SCREEN_ROUND);
}

TEST(ConfigTest, RoundIsMoreSpecific) {
    ResTable_config deviceConfig;
    memset(&deviceConfig, 0, sizeof(deviceConfig));
    deviceConfig.screenLayout2 = ResTable_config::SCREENROUND_YES;
    deviceConfig.screenLayout = ResTable_config::SCREENLONG_YES;

    ResTable_config targetConfigA;
    memset(&targetConfigA, 0, sizeof(targetConfigA));

    ResTable_config targetConfigB = targetConfigA;
    targetConfigB.screenLayout = ResTable_config::SCREENLONG_YES;

    ResTable_config targetConfigC = targetConfigB;
    targetConfigC.screenLayout2 = ResTable_config::SCREENROUND_YES;

    EXPECT_TRUE(targetConfigB.isBetterThan(targetConfigA, &deviceConfig));
    EXPECT_TRUE(targetConfigC.isBetterThan(targetConfigB, &deviceConfig));
}

}  // namespace android.
