/**
 * Copyright (C) 2018 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 <stdlib.h>
#include <string.h>

#include <android-base/logging.h>
#include <gtest/gtest.h>

#include "otapreopt_parameters.h"

namespace android {
namespace installd {

static bool ParseBool(const char* in) {
    if (strcmp(in, "true") == 0) {
        return true;
    }
    return false;
}

static const char* ParseNull(const char* arg) {
    return (strcmp(arg, "!") == 0) ? nullptr : arg;
}

class OTAPreoptTest : public testing::Test {
protected:
    virtual void SetUp() {
        setenv("ANDROID_LOG_TAGS", "*:f", 1);
        android::base::InitLogging(nullptr, android::base::StderrLogger);
    }

    void verifyPackageParameters(const OTAPreoptParameters& params,
                                 uint32_t version,
                                 bool versioned,
                                 const char** args) {
        //  otapreopt target-slot [version] dexopt {DEXOPT_PARAMETERS}
        int i = 0;
        if (version > 2 || (version == 2 && versioned)) {
            i += 4;
        } else {
            i += 3;
        }
        ASSERT_STREQ(params.target_slot.c_str(), args[1]);
        ASSERT_STREQ(params.apk_path, args[i++]);
        ASSERT_EQ(params.uid, static_cast<uid_t>(atoi(args[i++])));
        ASSERT_STREQ(params.pkgName, args[i++]);
        ASSERT_STREQ(params.instruction_set, args[i++]);
        ASSERT_EQ(params.dexopt_needed, atoi(args[i++]));
        ASSERT_STREQ(params.oat_dir, args[i++]);
        ASSERT_EQ(params.dexopt_flags, atoi(args[i++]));
        ASSERT_STREQ(params.compiler_filter, args[i++]);
        ASSERT_STREQ(params.volume_uuid, ParseNull(args[i++]));
        ASSERT_STREQ(params.shared_libraries, ParseNull(args[i++]));
        if (version > 1) {
            ASSERT_STREQ(params.se_info, ParseNull(args[i++]));
        } else {
            ASSERT_EQ(params.se_info, nullptr);
        }
        if (version > 2) {
            ASSERT_EQ(params.downgrade, ParseBool(args[i++]));
        } else {
            ASSERT_FALSE(params.downgrade);
        }
        if (version > 3) {
            ASSERT_EQ(params.target_sdk_version, atoi(args[i++]));
        } else {
             ASSERT_EQ(params.target_sdk_version, 0);
        }
        if (version > 4) {
            ASSERT_STREQ(params.profile_name, ParseNull(args[i++]));
        } else {
            ASSERT_STREQ(params.profile_name, "primary.prof");
        }
        if (version > 5) {
            ASSERT_STREQ(params.dex_metadata_path, ParseNull(args[i++]));
        } else {
            ASSERT_EQ(params.dex_metadata_path, nullptr);
        }
    }

    const char* getVersionCStr(uint32_t version) {
        switch (version) {
            case 1: return "1";
            case 2: return "2";
            case 3: return "3";
            case 4: return "4";
            case 5: return "5";
            case 6: return "6";
        }
        return nullptr;
    }

    std::vector<const char*> getArgs(uint32_t version, bool versioned) {
        std::vector<const char*> args;
        args.push_back("otapreopt");  // "otapreopt"
        args.push_back("a");  // slot
        if (versioned) {
            args.push_back(getVersionCStr(version));
        }
        args.push_back("dexopt");  // "dexopt"
        args.push_back("foo.apk");  // apk_path
        args.push_back("123");  // uid
        args.push_back("pkgname");  // pkg
        args.push_back("arm");  // isa
        args.push_back("1");  // dexopt_needed (DEX2OAT_FROM_SCRATCH)
        args.push_back("oat_dir");  // oat_dir
        args.push_back("0");  // dexopt_flags
        args.push_back("speed");  // filter
        args.push_back("!");  // volume
        args.push_back("shared.lib");  // libs

        if (version > 1) {
            args.push_back("!");  // seinfo
        }
        if (version > 2) {
            args.push_back("true");  // downgrade
        }
        if (version > 3) {
            args.push_back("28");  // sdk_version
        }
        if (version > 4) {
            args.push_back("split_a.prof");  // profile_name
        }
        if (version > 5) {
            args.push_back("dex_metadata.dm");  // dex_metadata_path
        }
        args.push_back(nullptr);  // we have to end with null.
        return args;
    }

    void VerifyReadArguments(uint32_t version, bool versioned) {
        OTAPreoptParameters params;
        std::vector<const char*> args = getArgs(version, versioned);
        ASSERT_TRUE(params.ReadArguments(args.size() - 1, args.data()));
        verifyPackageParameters(params, version, versioned, args.data());
    }
};

TEST_F(OTAPreoptTest, ReadArgumentsV1) {
    VerifyReadArguments(1, false);
}

TEST_F(OTAPreoptTest, ReadArgumentsV2Unversioned) {
    VerifyReadArguments(2, false);
}

TEST_F(OTAPreoptTest, ReadArgumentsV2) {
    VerifyReadArguments(2, true);
}

TEST_F(OTAPreoptTest, ReadArgumentsV3) {
    VerifyReadArguments(3, true);
}

TEST_F(OTAPreoptTest, ReadArgumentsV4) {
    VerifyReadArguments(4, true);
}

TEST_F(OTAPreoptTest, ReadArgumentsV5) {
    VerifyReadArguments(5, true);
}

TEST_F(OTAPreoptTest, ReadArgumentsV6) {
    VerifyReadArguments(6, true);
}

TEST_F(OTAPreoptTest, ReadArgumentsFailToManyArgs) {
    OTAPreoptParameters params;
    std::vector<const char*> args = getArgs(5, true);
    args[2] = "3";  // pretend it's version 3. It should fail since there are too many args.
    ASSERT_FALSE(params.ReadArguments(args.size() - 1, args.data()));
}

TEST_F(OTAPreoptTest, ReadArgumentsFailInsufficientArgs) {
    OTAPreoptParameters params;
    std::vector<const char*> args = getArgs(4, true);
    args[2] = "5";  // pretend it's version 5. It should fail since there are insufficient args.
    ASSERT_FALSE(params.ReadArguments(args.size() - 1, args.data()));
}

TEST_F(OTAPreoptTest, ReadArgumentsFailInvalidDexopt) {
    OTAPreoptParameters params;
    std::vector<const char*> args = getArgs(4, true);
    args[3] = "dexopt-invalid";
    ASSERT_FALSE(params.ReadArguments(args.size() - 1, args.data()));
}

TEST_F(OTAPreoptTest, ReadArgumentsFailInvalidSlot) {
    OTAPreoptParameters params;
    std::vector<const char*> args = getArgs(3, true);
    args[1] = "invalid-slot???";
    ASSERT_FALSE(params.ReadArguments(args.size() - 1, args.data()));
}

}  // namespace installd
}  // namespace android
