/**
 * 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 "installd_constants.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++]);
        const int 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);
        }
        if (version > 6) {
            ASSERT_STREQ(params.compilation_reason, ParseNull(args[i++]));
        } else {
            ASSERT_STREQ(params.compilation_reason, "ab-ota");
        }
        if (version > 7) {
            ASSERT_EQ(params.dexopt_flags, dexopt_flags);
        } else {
            ASSERT_EQ(params.dexopt_flags, dexopt_flags | DEXOPT_GENERATE_COMPACT_DEX);
        }
    }

    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";
            case 7: return "7";
            case 8: return "8";
            case 9: return "9";
        }
        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
        }
        if (version > 6) {
            args.push_back("ab-ota-test");  // compilation_reason
        }
        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, ReadArgumentsV7) {
    VerifyReadArguments(7, 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
