/*
 * Copyright (c) 2021-2022 Huawei Device Co., Ltd.
 * 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 <gtest/gtest.h>

#define private public
#define protected public
#include "bool_wrapper.h"
#include "int_wrapper.h"
#include "long_wrapper.h"
#include "refbase.h"
#include "skills.h"
#include "string_wrapper.h"
#undef private
#undef protected
#include "patterns_matcher.h"

using namespace testing::ext;
using namespace OHOS::AAFwk;
using OHOS::Parcel;

namespace OHOS {
namespace AAFwk {
static const int LARGE_STR_LEN = 65534;
static const int SET_COUNT = 20;
static const int DISMATCH_TYPE = 67584;
static const int DISMATCH_DATA = -102;
class SkillsBaseTest : public testing::Test {
public:
    SkillsBaseTest()
    {}
    ~SkillsBaseTest()
    {}
    static void SetUpTestCase(void);
    static void TearDownTestCase(void);
    void SetUp();
    void TearDown();

    std::shared_ptr<Skills> base_ = nullptr;
    std::shared_ptr<PatternsMatcher> PatternsMatcherIn_ = nullptr;
    void CompareSkills(const std::shared_ptr<Skills> &skills1, const std::shared_ptr<Skills> &skills2) const;
};

void SkillsBaseTest::SetUpTestCase(void)
{}

void SkillsBaseTest::TearDownTestCase(void)
{}

void SkillsBaseTest::SetUp(void)
{
    base_ = std::make_shared<Skills>();
    PatternsMatcherIn_ = std::make_shared<PatternsMatcher>();
}

void SkillsBaseTest::TearDown(void)
{}

/**
 * @tc.number: AaFwk_Skills_Parcelable_0100
 * @tc.name: Marshalling/Unmarshalling
 * @tc.desc: marshalling Skills, and then check result.
 */
HWTEST_F(SkillsBaseTest, AaFwk_Skills_Parcelable_0100, Function | MediumTest | Level1)
{
    std::shared_ptr<Skills> SkillsIn_ = std::make_shared<Skills>();
    if (SkillsIn_ == nullptr) {
        return;
    }
    SkillsIn_->AddEntity("12345");
    SkillsIn_->AddAction("12345");
    SkillsIn_->AddAuthority("12345");
    SkillsIn_->AddScheme("12345");
    SkillsIn_->AddPath("12345");
    SkillsIn_->AddSchemeSpecificPart("12345");
    SkillsIn_->AddType("12345");
    WantParams wantParams;
    std::string keyStr = "12345667";
    bool valueBool = true;
    wantParams.SetParam(keyStr, Boolean::Box(valueBool));
    SkillsIn_->SetWantParams(wantParams);

    Parcel in;
    std::shared_ptr<Skills> SkillsOut_(Skills::Unmarshalling(in));
    SkillsIn_->Marshalling(in);
    if (SkillsOut_ != nullptr) {
        CompareSkills(SkillsIn_, SkillsOut_);
        EXPECT_EQ(valueBool, Boolean::Unbox(IBoolean::Query(SkillsOut_->GetWantParams().GetParam(keyStr))));
    }
}

/**
 * @tc.number: AaFwk_Skills_Parcelable_0200
 * @tc.name: Marshalling/Unmarshalling
 * @tc.desc: marshalling Skills, and then check result.
 */
HWTEST_F(SkillsBaseTest, AaFwk_Skills_Parcelable_0200, Function | MediumTest | Level1)
{
    std::shared_ptr<Skills> SkillsIn_ = std::make_shared<Skills>();
    if (SkillsIn_ == nullptr) {
        return;
    }

    SkillsIn_->AddEntity("@#¥#3243adsafdf_中文");
    SkillsIn_->AddAction("@#¥#3243adsafdf_中文");
    SkillsIn_->AddAuthority("@#¥#3243adsafdf_中文");
    SkillsIn_->AddScheme("@#¥#3243adsafdf_中文");
    SkillsIn_->AddPath("@#¥#3243adsafdf_中文");
    SkillsIn_->AddSchemeSpecificPart("@#¥#3243adsafdf_中文");
    SkillsIn_->AddType("@#¥#3243adsafdf_中文");
    WantParams wantParams;
    std::string keyStr = "@#¥#3243adsafdf_中文";
    long valueLong = 12345L;
    wantParams.SetParam(keyStr, Long::Box(valueLong));
    EXPECT_EQ(valueLong, Long::Unbox(ILong::Query(wantParams.GetParam(keyStr))));

    SkillsIn_->SetWantParams(wantParams);

    Parcel in;
    SkillsIn_->Marshalling(in);
    std::shared_ptr<Skills> SkillsOut_(Skills::Unmarshalling(in));

    if (SkillsOut_ != nullptr) {
        CompareSkills(SkillsIn_, SkillsOut_);
        long result = Long::Unbox(ILong::Query(SkillsOut_->GetWantParams().GetParam(keyStr)));
        EXPECT_EQ(valueLong, result);
    }
}

/**
 * @tc.number: AaFwk_Skills_Parcelable_0300
 * @tc.name: Marshalling/Unmarshalling
 * @tc.desc: marshalling Skills, and then check result.
 */
HWTEST_F(SkillsBaseTest, AaFwk_Skills_Parcelable_0300, Function | MediumTest | Level1)
{
    std::shared_ptr<Skills> SkillsIn_ = std::make_shared<Skills>();
    if (SkillsIn_ == nullptr) {
        return;
    }

    SkillsIn_->AddEntity("");
    SkillsIn_->AddAction("");
    SkillsIn_->AddAuthority("");
    SkillsIn_->AddScheme("");
    SkillsIn_->AddPath("");
    SkillsIn_->AddSchemeSpecificPart("");
    SkillsIn_->AddType("");
    WantParams wantParams;
    std::string keyStr = "";
    int valueInt = 123;
    wantParams.SetParam(keyStr, Integer::Box(valueInt));

    SkillsIn_->SetWantParams(wantParams);
    EXPECT_EQ(valueInt, Integer::Unbox(IInteger::Query(wantParams.GetParam(keyStr))));

    Parcel in;
    SkillsIn_->Marshalling(in);
    std::shared_ptr<Skills> SkillsOut_(Skills::Unmarshalling(in));

    if (SkillsOut_ != nullptr) {
        CompareSkills(SkillsIn_, SkillsOut_);
        EXPECT_EQ(valueInt, Integer::Unbox(IInteger::Query(SkillsOut_->GetWantParams().GetParam(keyStr))));
    }
}

/**
 * @tc.number: AaFwk_Skills_Parcelable_0400
 * @tc.name: Marshalling/Unmarshalling
 * @tc.desc: marshalling Skills, and then check result.
 */
HWTEST_F(SkillsBaseTest, AaFwk_Skills_Parcelable_0400, Function | MediumTest | Level1)
{
    std::shared_ptr<Skills> SkillsIn_ = std::make_shared<Skills>();
    if (SkillsIn_ == nullptr) {
        return;
    }
    SkillsIn_->AddEntity("12345");
    SkillsIn_->AddAction("12345");
    SkillsIn_->AddAuthority("12345");
    SkillsIn_->AddScheme("12345");
    SkillsIn_->AddPath("12345");
    SkillsIn_->AddSchemeSpecificPart("12345");
    SkillsIn_->AddType("12345");
    SkillsIn_->AddEntity("@#¥#3243adsafdf_中文");
    SkillsIn_->AddAction("@#¥#3243adsafdf_中文");
    SkillsIn_->AddAuthority("@#¥#3243adsafdf_中文");
    SkillsIn_->AddScheme("@#¥#3243adsafdf_中文");
    SkillsIn_->AddPath("@#¥#3243adsafdf_中文");
    SkillsIn_->AddSchemeSpecificPart("@#¥#3243adsafdf_中文");
    SkillsIn_->AddType("@#¥#3243adsafdf_中文");
    SkillsIn_->AddEntity("");
    SkillsIn_->AddAction("");
    SkillsIn_->AddAuthority("");
    SkillsIn_->AddScheme("");
    SkillsIn_->AddPath("");
    SkillsIn_->AddSchemeSpecificPart("");
    SkillsIn_->AddType("");
    WantParams wantParams;
    std::string keyStr = "12345667";
    std::string valueString = "123";
    wantParams.SetParam(keyStr, String::Box(valueString));
    SkillsIn_->SetWantParams(wantParams);

    Parcel in;
    SkillsIn_->Marshalling(in);
    std::shared_ptr<Skills> SkillsOut_(Skills::Unmarshalling(in));

    if (SkillsOut_ != nullptr) {
        CompareSkills(SkillsIn_, SkillsOut_);
        EXPECT_EQ(valueString, String::Unbox(IString::Query(SkillsOut_->GetWantParams().GetParam(keyStr))));
    }
}

void SkillsBaseTest::CompareSkills(const std::shared_ptr<Skills> &skills1, const std::shared_ptr<Skills> &skills2) const
{
    EXPECT_EQ(skills1->CountEntities(), skills2->CountEntities());
    EXPECT_EQ(skills1->CountActions(), skills2->CountActions());
    EXPECT_EQ(skills1->CountAuthorities(), skills2->CountAuthorities());
    EXPECT_EQ(skills1->CountSchemes(), skills2->CountSchemes());
    EXPECT_EQ(skills1->CountPaths(), skills2->CountPaths());
    EXPECT_EQ(skills1->CountSchemeSpecificParts(), skills2->CountSchemeSpecificParts());
    EXPECT_EQ(skills1->CountTypes(), skills2->CountTypes());

    int count = skills1->CountEntities();
    for (int i = 0; i < count; i++) {
        EXPECT_EQ(skills1->GetEntity(i), skills1->GetEntity(i));
    }
    count = skills1->CountActions();
    for (int i = 0; i < count; i++) {
        EXPECT_EQ(skills1->GetAction(i), skills1->GetAction(i));
    }
    count = skills1->CountAuthorities();
    for (int i = 0; i < count; i++) {
        EXPECT_EQ(skills1->GetAuthority(i), skills1->GetAuthority(i));
    }
    count = skills1->CountSchemes();
    for (int i = 0; i < count; i++) {
        EXPECT_EQ(skills1->GetScheme(i), skills1->GetScheme(i));
    }
    count = skills1->CountPaths();
    for (int i = 0; i < count; i++) {
        EXPECT_EQ(skills1->GetPath(i), skills1->GetPath(i));
    }
    count = skills1->CountSchemeSpecificParts();
    for (int i = 0; i < count; i++) {
        EXPECT_EQ(skills1->GetSchemeSpecificPart(i), skills1->GetSchemeSpecificPart(i));
    }
    count = skills1->CountTypes();
    for (int i = 0; i < count; i++) {
        EXPECT_EQ(skills1->GetType(i), skills1->GetType(i));
    }

    std::set<std::string> key1;
    std::set<std::string> key2;
    key1 = skills1->GetWantParams().KeySet();
    key2 = skills2->GetWantParams().KeySet();
    EXPECT_EQ(key1.size(), key2.size());

    if (key1.size() > 0 && key2.size() > 0) {
        std::set<std::string>::iterator iter1 = key1.begin();
        std::set<std::string>::iterator iter2 = key2.begin();
        for (; (iter1 != key1.end() && iter2 != key2.end()); iter1++, iter2++) {
            EXPECT_EQ(*iter1, *iter2);
        }
    }
}

/**
 * @tc.number: AaFwk_Skills_Entities_0100
 * @tc.name: CountEntitie/HasEntity/GetEntity
 * @tc.desc: Verify the function when the input string contains special characters.
 */
HWTEST_F(SkillsBaseTest, AaFwk_Skills_Entities_0100, Function | MediumTest | Level1)
{
    std::string empty;
    std::string entities = "entities.system.test";
    EXPECT_EQ(0, base_->CountEntities());
    EXPECT_EQ(false, base_->HasEntity(entities));
    EXPECT_EQ(empty, base_->GetEntity(0));

    base_->RemoveEntity(entities);
    EXPECT_EQ(0, base_->CountEntities());
    EXPECT_EQ(false, base_->HasEntity(entities));
}
/**
 * @tc.number: AaFwk_Skills_GetEntities_0100
 * @tc.name: AddEntity and GetEntities
 * @tc.desc: Verify AddEntity and GetEntities.
 */
HWTEST_F(SkillsBaseTest, AaFwk_Skills_GetEntities_0100, Function | MediumTest | Level1)
{
    std::string entity = "12345667";
    base_->AddEntity(entity);

    size_t length = base_->GetEntities().size();

    EXPECT_EQ((size_t)1, length);
    EXPECT_EQ(entity, base_->GetEntities().at(0));
}

/**
 * @tc.number: AaFwk_Skills_Authorities_0100
 * @tc.name: CountEntitie/HasEntity/GetEntity
 * @tc.desc: Verify the function when the input string has a long size.
 */
HWTEST_F(SkillsBaseTest, AaFwk_Skills_Authorities_0100, Function | MediumTest | Level1)
{
    std::string empty;
    std::string authorities = "authorities.system.test";
    EXPECT_EQ(0, base_->CountAuthorities());
    EXPECT_EQ(false, base_->HasAuthority(authorities));
    EXPECT_EQ(empty, base_->GetAuthority(0));

    base_->RemoveAuthority(authorities);
    EXPECT_EQ(0, base_->CountAuthorities());
    EXPECT_EQ(false, base_->HasAuthority(authorities));
}

/**
 * @tc.number: AaFwk_Skills_Path_0300
 * @tc.name: CountPaths/HasPath/GetPath
 * @tc.desc: Verify the function when the input string is overrided.
 */
HWTEST_F(SkillsBaseTest, AaFwk_Skills_Path_0300, Function | MediumTest | Level1)
{
    std::string empty;
    std::string path = "paths.system.test";
    PatternsMatcher pm(path, MatchType::DEFAULT);
    base_->AddPath(pm);

    EXPECT_EQ(1, base_->CountPaths());
    EXPECT_EQ(true, base_->HasPath(path));
    EXPECT_EQ(path, base_->GetPath(0));

    base_->RemovePath(pm);
    EXPECT_EQ(0, base_->CountPaths());
    EXPECT_EQ(false, base_->HasPath(path));

    Parcel parcel;
    EXPECT_EQ(true, base_->Marshalling(parcel));
}

/**
 * @tc.number: AaFwk_Skills_Action_0100
 * @tc.name: AddAction/CountActions/HasAction/GetAction
 * @tc.desc: Verify the function when the input string is set 20 times.
 */
HWTEST_F(SkillsBaseTest, AaFwk_Skills_Action_0100, Function | MediumTest | Level1)
{
    std::string empty;
    std::string action = "action.system.test";
    int actionCount = 1;

    for (int i = 0; i < SET_COUNT; i++) {
        base_->AddAction(action);
    }

    EXPECT_EQ(actionCount, base_->CountActions());
    EXPECT_EQ(true, base_->HasAction(action));
    EXPECT_EQ(action, base_->GetAction(0));

    base_->RemoveAction(action);
    EXPECT_EQ(0, base_->CountActions());
    EXPECT_EQ(false, base_->HasAction(action));
}

/**
 * @tc.number: AaFwk_Skills_ActionsIterator_0100
 * @tc.name: ActionsIterator
 * @tc.desc: Test the function of ActionsIterator.
 */
HWTEST_F(SkillsBaseTest, AaFwk_Skills_ActionsIterator_0100, Function | MediumTest | Level1)
{
    base_->actions_.push_back("a");
    base_->actions_.push_back("b");
    auto iter = base_->ActionsIterator();
    EXPECT_EQ(*iter, "a");
}

/**
 * @tc.number: AaFwk_Skills_Entity_0100
 * @tc.name: CountEntities/HasEntity/CountEntities/GetEntity
 * @tc.desc: Verify the function when the input string is default.
 */
HWTEST_F(SkillsBaseTest, AaFwk_Skills_Entity_0100, Function | MediumTest | Level1)
{
    std::string empty;
    std::string entity = "entity.system.test";
    int entityCount = 1;

    for (int i = 0; i < SET_COUNT; i++) {
        base_->AddEntity(entity);
    }

    EXPECT_EQ(entityCount, base_->CountEntities());
    EXPECT_EQ(true, base_->HasEntity(entity));
    EXPECT_EQ(entity, base_->GetEntity(0));

    base_->RemoveEntity(entity);
    EXPECT_EQ(0, base_->CountEntities());
    EXPECT_EQ(false, base_->HasEntity(entity));
}

/**
 * @tc.number: AaFwk_Skills_Authority_0100
 * @tc.name: CountAuthorities/HasAuthority/GetAuthority
 * @tc.desc: Verify the function when the input string contains special characters.
 */
HWTEST_F(SkillsBaseTest, AaFwk_Skills_Authority_0100, Function | MediumTest | Level1)
{
    std::string empty;
    std::string authority = "Authority.system.test";
    int authorityCount = 1;

    for (int i = 0; i < SET_COUNT; i++) {
        base_->AddAuthority(authority);
    }

    EXPECT_EQ(authorityCount, base_->CountAuthorities());
    EXPECT_EQ(true, base_->HasAuthority(authority));
    EXPECT_EQ(authority, base_->GetAuthority(0));

    base_->RemoveAuthority(authority);
    EXPECT_EQ(0, base_->CountAuthorities());
    EXPECT_EQ(false, base_->HasAuthority(authority));
}

/**
 * @tc.number: AaFwk_Skills_Path_0100
 * @tc.name: CountPaths/HasPath/GetPath
 * @tc.desc: Verify the function when the input string contains special characters.
 */
HWTEST_F(SkillsBaseTest, AaFwk_Skills_Path_0100, Function | MediumTest | Level1)
{
    std::string empty;
    std::string path = "Path.system.test";
    int pathCount = 1;

    for (int i = 0; i < SET_COUNT; i++) {
        base_->AddPath(path);
    }

    EXPECT_EQ(pathCount, base_->CountPaths());
    EXPECT_EQ(true, base_->HasPath(path));
    EXPECT_EQ(path, base_->GetPath(0));

    base_->RemovePath(path);
    EXPECT_EQ(0, base_->CountPaths());
    EXPECT_EQ(false, base_->HasPath(path));
}

/**
 * @tc.number: AaFwk_Skills_Scheme_0100
 * @tc.name: CountSchemes/HasScheme/GetScheme
 * @tc.desc: Verify the function when the input string contains special characters.
 */
HWTEST_F(SkillsBaseTest, AaFwk_Skills_Scheme_0100, Function | MediumTest | Level1)
{
    std::string empty;
    std::string scheme = "scheme.system.test";
    int schemeCount = 1;

    for (int i = 0; i < SET_COUNT; i++) {
        base_->AddScheme(scheme);
    }

    EXPECT_EQ(schemeCount, base_->CountSchemes());
    EXPECT_EQ(true, base_->HasScheme(scheme));
    EXPECT_EQ(scheme, base_->GetScheme(0));

    base_->RemoveScheme(scheme);
    EXPECT_EQ(0, base_->CountSchemes());
    EXPECT_EQ(false, base_->HasScheme(scheme));
}

/**
 * @tc.number: AaFwk_Skills_SchemeSpecificPart_0100
 * @tc.name: CountSchemeSpecificParts/HasSchemeSpecificPart/GetSchemeSpecificPart
 * @tc.desc: Verify the function when the input string contains special characters.
 */
HWTEST_F(SkillsBaseTest, AaFwk_Skills_SchemeSpecificPart_0100, Function | MediumTest | Level1)
{
    std::string empty;
    std::string schemespecificpart = "schemespecificpart.system.test";
    int schemespecificpartCount = 1;

    for (int i = 0; i < SET_COUNT; i++) {
        base_->AddSchemeSpecificPart(schemespecificpart);
    }

    EXPECT_EQ(schemespecificpartCount, base_->CountSchemeSpecificParts());
    EXPECT_EQ(true, base_->HasSchemeSpecificPart(schemespecificpart));
    EXPECT_EQ(schemespecificpart, base_->GetSchemeSpecificPart(0));

    base_->RemoveSchemeSpecificPart(schemespecificpart);
    EXPECT_EQ(0, base_->CountSchemeSpecificParts());
    EXPECT_EQ(false, base_->HasSchemeSpecificPart(schemespecificpart));
}

/**
 * @tc.number: AaFwk_Skills_Type_0100
 * @tc.name: CountTypes/HasType/GetType
 * @tc.desc: Verify the function when the input string contains special characters.
 */
HWTEST_F(SkillsBaseTest, AaFwk_Skills_Type_0100, Function | MediumTest | Level1)
{
    std::string empty;
    std::string type = "type/system.test";
    int typeCount = 1;

    for (int i = 0; i < SET_COUNT; i++) {
        base_->AddType(type);
    }

    EXPECT_EQ(typeCount, base_->CountTypes());
    EXPECT_EQ(true, base_->HasType(type));
    EXPECT_EQ(type, base_->GetType(0));

    base_->RemoveType(type);
    EXPECT_EQ(0, base_->CountTypes());
    EXPECT_EQ(false, base_->HasType(type));
}

/**
 * @tc.number: AaFwk_Skills_Actions_0100
 * @tc.name: CountActions/HasAuthority/GetAuthority
 * @tc.desc: Verify the function when the input string contains special characters.
 */
HWTEST_F(SkillsBaseTest, AaFwk_Skills_Actions_0100, Function | MediumTest | Level1)
{
    std::string empty;
    std::string actions = "actions.system.test";
    EXPECT_EQ(0, base_->CountActions());
    EXPECT_EQ(false, base_->HasAuthority(actions));
    EXPECT_EQ(empty, base_->GetAuthority(0));

    base_->RemoveAuthority(actions);
    EXPECT_EQ(0, base_->CountActions());
    EXPECT_EQ(false, base_->HasAuthority(actions));
}

/**
 * @tc.number: AaFwk_Skills_Schemes_0100
 * @tc.name: CountSchemes/HasAuthority/GetAuthority
 * @tc.desc: Verify the function when the input string contains special characters.
 */
HWTEST_F(SkillsBaseTest, AaFwk_Skills_Schemes_0100, Function | MediumTest | Level1)
{
    std::string empty;
    std::string schemes = "schemes.system.test";
    EXPECT_EQ(0, base_->CountSchemes());
    EXPECT_EQ(false, base_->HasAuthority(schemes));
    EXPECT_EQ(empty, base_->GetAuthority(0));

    base_->RemoveAuthority(schemes);
    EXPECT_EQ(0, base_->CountSchemes());
    EXPECT_EQ(false, base_->HasAuthority(schemes));
}

/**
 * @tc.number: AaFwk_Skills_SchemeSpecificParts_0100
 * @tc.name: CountSchemeSpecificParts/HasAuthority/GetAuthority
 * @tc.desc: Verify the function when the input string contains special characters.
 */
HWTEST_F(SkillsBaseTest, AaFwk_Skills_SchemeSpecificParts_0100, Function | MediumTest | Level1)
{
    std::string empty;
    std::string schemespecificparts = "schemespecificparts.system.test";
    EXPECT_EQ(0, base_->CountSchemeSpecificParts());
    EXPECT_EQ(false, base_->HasAuthority(schemespecificparts));
    EXPECT_EQ(empty, base_->GetAuthority(0));

    base_->RemoveAuthority(schemespecificparts);
    EXPECT_EQ(0, base_->CountSchemeSpecificParts());
    EXPECT_EQ(false, base_->HasAuthority(schemespecificparts));
}

/**
 * @tc.number: AaFwk_Skills_Types_0100
 * @tc.name: CountTypes/HasAuthority/GetAuthority
 * @tc.desc: Verify the function when the input string contains special characters.
 */
HWTEST_F(SkillsBaseTest, AaFwk_Skills_Types_0100, Function | MediumTest | Level1)
{
    std::string empty;
    std::string types = "types.system.test";
    GTEST_LOG_(INFO) << "---------------a ";
    EXPECT_EQ(0, base_->CountTypes());
    GTEST_LOG_(INFO) << "---------------b ";
    EXPECT_EQ(false, base_->HasAuthority(types));
    GTEST_LOG_(INFO) << "---------------1 ";
    EXPECT_EQ(empty, base_->GetAuthority(0));
    GTEST_LOG_(INFO) << "---------------2 ";

    base_->RemoveAuthority(types);
    EXPECT_EQ(0, base_->CountTypes());
    EXPECT_EQ(false, base_->HasAuthority(types));
}

/**
 * @tc.number: AaFwk_Skills_Action_0200
 * @tc.name: CountActions/HasAction/GetAction
 * @tc.desc: Verify the function when action is not exist.
 */
HWTEST_F(SkillsBaseTest, AaFwk_Skills_Action_0200, Function | MediumTest | Level1)
{
    std::string empty;
    std::string action = "action.system.test";
    EXPECT_EQ(0, base_->CountActions());
    EXPECT_EQ(false, base_->HasAction(action));
    EXPECT_EQ(empty, base_->GetAction(0));

    base_->RemoveAction(action);
    EXPECT_EQ(0, base_->CountActions());
    EXPECT_EQ(false, base_->HasAction(action));
}

/**
 * @tc.number: AaFwk_Skills_Authority_0200
 * @tc.name: CountAuthorities/HasAuthority/GetAuthority
 * @tc.desc: Verify the function when action is not exist.
 */
HWTEST_F(SkillsBaseTest, AaFwk_Skills_Authority_0200, Function | MediumTest | Level1)
{
    std::string empty;
    std::string authority = "authority.system.test";
    EXPECT_EQ(0, base_->CountAuthorities());
    EXPECT_EQ(false, base_->HasAuthority(authority));
    EXPECT_EQ(empty, base_->GetAuthority(0));

    base_->RemoveAuthority(authority);
    EXPECT_EQ(0, base_->CountAuthorities());
    EXPECT_EQ(false, base_->HasAuthority(authority));
}

/**
 * @tc.number: AaFwk_Skills_Path_0200
 * @tc.name: CountPaths/HasPath/GetPath
 * @tc.desc: Verify the function when action is not exist.
 */
HWTEST_F(SkillsBaseTest, AaFwk_Skills_Path_0200, Function | MediumTest | Level1)
{
    std::string empty;
    std::string path = "path.system.test";
    base_->AddPath(path, MatchType::DEFAULT);

    EXPECT_EQ(1, base_->CountPaths());
    EXPECT_EQ(true, base_->HasPath(path));
    EXPECT_EQ(path, base_->GetPath(0));

    base_->RemovePath(path, MatchType::DEFAULT);
    EXPECT_EQ(0, base_->CountPaths());
    EXPECT_EQ(false, base_->HasPath(path));
}

/**
 * @tc.number: AaFwk_Skills_Scheme_0200
 * @tc.name: CountSchemes/HasScheme/GetScheme
 * @tc.desc: Verify the function when action is not exist.
 */
HWTEST_F(SkillsBaseTest, AaFwk_Skills_Scheme_0200, Function | MediumTest | Level1)
{
    std::string empty;
    std::string scheme = "scheme.system.test";
    EXPECT_EQ(0, base_->CountSchemes());
    EXPECT_EQ(false, base_->HasScheme(scheme));
    EXPECT_EQ(empty, base_->GetScheme(0));

    base_->RemoveScheme(scheme);
    EXPECT_EQ(0, base_->CountSchemes());
    EXPECT_EQ(false, base_->HasScheme(scheme));
}

/**
 * @tc.number: AaFwk_Skills_SchemeSpecificPart_0200
 * @tc.name: CountSchemeSpecificParts/HasSchemeSpecificPart/GetSchemeSpecificPart
 * @tc.desc: Verify the function when action is not exist.
 */
HWTEST_F(SkillsBaseTest, AaFwk_Skills_SchemeSpecificPart_0200, Function | MediumTest | Level1)
{
    std::string empty;
    std::string schemespecificpart = "schemespecificpart.system.test";
    EXPECT_EQ(0, base_->CountSchemeSpecificParts());
    EXPECT_EQ(false, base_->HasSchemeSpecificPart(schemespecificpart));
    EXPECT_EQ(empty, base_->GetSchemeSpecificPart(0));

    base_->RemoveSchemeSpecificPart(schemespecificpart);
    EXPECT_EQ(0, base_->CountSchemeSpecificParts());
    EXPECT_EQ(false, base_->HasSchemeSpecificPart(schemespecificpart));
}

/**
 * @tc.number: AaFwk_Skills_Type_0300
 * @tc.name: CountTypes/HasType/GetType
 * @tc.desc: Verify the function when action is not exist.
 */
HWTEST_F(SkillsBaseTest, AaFwk_Skills_Type_0300, Function | MediumTest | Level1)
{
    std::string empty;
    std::string type = "type.system.test";
    EXPECT_EQ(0, base_->CountTypes());

    EXPECT_EQ(false, base_->HasType(type));
    EXPECT_EQ(empty, base_->GetType(0));

    base_->RemoveType(type);
    EXPECT_EQ(0, base_->CountTypes());
    EXPECT_EQ(false, base_->HasType(type));
}

using SkillsMatchType = std::tuple<std::string, std::string, bool>;
class SkillsMatchTest : public testing::TestWithParam<SkillsMatchType> {
public:
    SkillsMatchTest()
    {}
    ~SkillsMatchTest()
    {}
    static void SetUpTestCase(void);
    static void TearDownTestCase(void);
    void SetUp();
    void TearDown();
    std::shared_ptr<Skills> skills_ = nullptr;
};

void SkillsMatchTest::SetUpTestCase(void)
{}

void SkillsMatchTest::TearDownTestCase(void)
{}

void SkillsMatchTest::SetUp(void)
{
    skills_ = std::make_shared<Skills>();
}

void SkillsMatchTest::TearDown(void)
{}

/**
 * @tc.number: AaFwk_Skills_match_0100
 * @tc.name: CountTypes/HasType/GetType
 * @tc.desc: Verify whether parameter change.
 */
HWTEST_P(SkillsMatchTest, AaFwk_Skills_match_0100, Function | MediumTest | Level1)
{
    std::string filterEntity = "entity.system.entity1";
    std::string filterAction1 = "action.system.action1";
    std::string filterAction2 = "action.system.action2";
    std::string wantEntity = std::get<0>(GetParam());
    std::string wantAction = std::get<1>(GetParam());
    bool result = std::get<2>(GetParam());

    skills_->AddEntity(filterEntity);
    skills_->AddAction(filterAction1);
    skills_->AddAction(filterAction2);

    Want want;
    want.AddEntity(wantEntity);
    want.SetAction(wantAction);

    EXPECT_EQ(result, skills_->Match(want));
}

INSTANTIATE_TEST_SUITE_P(SkillsMatchTestP, SkillsMatchTest,
    testing::Values(SkillsMatchType("entity.system.entityA", "action.system.actionA", false),
        SkillsMatchType("entity.system.entity1", "action.system.actionA", false),
        SkillsMatchType("entity.system.entityA", "action.system.action2", false),
        SkillsMatchType("entity.system.entity1", "action.system.action1", true)));

/**
 * @tc.name: AaFwk_Skills_match_0200
 * @tc.desc: Verify Matching rules action segment
 * @tc.type: FUNC
 * @tc.require: I5PZK2
 */
HWTEST_F(SkillsBaseTest, AaFwk_Skills_match_0200, Function | MediumTest | Level1)
{
    Skills skills;
    std::string filterEntity = "entity.system.entity1";
    skills.AddEntity(filterEntity);
    Want want;
    want.AddEntity(filterEntity);
    // Both actions are empty.
    EXPECT_EQ(true, skills.Match(want));
}

/**
 * @tc.name: AaFwk_Skills_match_0300
 * @tc.desc: Verify Matching rules action segment
 * @tc.type: FUNC
 * @tc.require: I5PZK2
 */
HWTEST_F(SkillsBaseTest, AaFwk_Skills_match_0300, Function | MediumTest | Level1)
{
    Skills skills;
    std::string filterEntity = "entity.system.entity1";
    skills.AddEntity(filterEntity);
    Want want;
    want.AddEntity(filterEntity);
    want.SetAction("action.system.action1");
    // empty actions in skill vs non-empty actions in want
    EXPECT_EQ(false, skills.Match(want));
}

/**
 * @tc.name: AaFwk_Skills_match_0400
 * @tc.desc: Verify Matching rules action segment
 * @tc.type: FUNC
 * @tc.require: I5PZK2
 */
HWTEST_F(SkillsBaseTest, AaFwk_Skills_match_0400, Function | MediumTest | Level1)
{
    Skills skills;
    std::string filterEntity = "entity.system.entity1";
    std::string filterAction1 = "action.system.action1";
    std::string filterAction2 = "action.system.action2";
    skills.AddEntity(filterEntity);
    skills.AddAction(filterAction1);
    skills.AddAction(filterAction2);
    Want want;
    want.AddEntity(filterEntity);
    want.SetAction(filterAction1);
    // actions that in skill contains non-empty actions in want
    EXPECT_EQ(true, skills.Match(want));
}

/**
 * @tc.name: AaFwk_Skills_match_0500
 * @tc.desc: Verify Matching rules action segment
 * @tc.type: FUNC
 * @tc.require: I5PZK2
 */
HWTEST_F(SkillsBaseTest, AaFwk_Skills_match_0600, Function | MediumTest | Level1)
{
    Skills skills;
    std::string filterEntity = "entity.system.entity1";
    std::string filterAction1 = "action.system.action1";
    std::string filterAction2 = "action.system.action2";
    skills.AddEntity(filterEntity);
    skills.AddAction(filterAction2);
    Want want;
    want.AddEntity(filterEntity);
    // non-empty actions that in skill vs empty actions in want
    EXPECT_EQ(false, skills.Match(want));
}

/**
 * @tc.name: AaFwk_Skills_match_0600
 * @tc.desc: Verify Matching rules action segment
 * @tc.type: FUNC
 * @tc.require: I5PZK2
 */
HWTEST_F(SkillsBaseTest, AaFwk_Skills_match_0500, Function | MediumTest | Level1)
{
    Skills skills;
    std::string filterEntity = "entity.system.entity1";
    std::string filterAction1 = "action.system.action1";
    std::string filterAction2 = "action.system.action2";
    skills.AddEntity(filterEntity);
    skills.AddAction(filterAction2);
    Want want;
    want.AddEntity(filterEntity);
    want.SetAction(filterAction1);
    // actions that in skill doesn't contain non-empty actions in want
    EXPECT_EQ(false, skills.Match(want));
}

/**
 * @tc.number: AaFwk_Skills_Skills_0100
 * @tc.name: Skills() and Skills(Skills)
 * @tc.desc:  Verify Skills().
 */
HWTEST_F(SkillsBaseTest, AaFwk_Skills_Skills_0100, Function | MediumTest | Level1)
{
    Skills skills;

    EXPECT_EQ(0, skills.CountEntities());
    EXPECT_EQ(0, skills.CountActions());
    EXPECT_EQ(0, skills.CountAuthorities());
    EXPECT_EQ(0, skills.CountSchemes());

    EXPECT_EQ(0, skills.CountPaths());
    EXPECT_EQ(0, skills.CountSchemeSpecificParts());
    EXPECT_EQ(0, skills.CountTypes());
    EXPECT_EQ(0, skills.GetWantParams().Size());
}

/**
 * @tc.number: AaFwk_Skills_Skills_0200
 * @tc.name: Skills() and Skills(Skills)
 * @tc.desc:  Verify Skills().
 */
HWTEST_F(SkillsBaseTest, AaFwk_Skills_Skills_0200, Function | MediumTest | Level1)
{
    Skills skillsBase;
    std::string entityString = "entity";
    skillsBase.AddEntity(entityString);
    std::string actionString = "action";
    skillsBase.AddAction(actionString);
    std::string authorityString = "authority";
    skillsBase.AddAuthority(authorityString);
    std::string schemeString = "scheme";
    skillsBase.AddScheme(schemeString);
    std::string pathString = "path";
    skillsBase.AddPath(pathString);
    std::string schemeSpecificPartsString = "schemeSpecificParts";
    skillsBase.AddSchemeSpecificPart(schemeSpecificPartsString);
    std::string typeString = "/type";
    skillsBase.AddType(typeString);
    Skills skills(skillsBase);

    EXPECT_EQ(entityString, skills.GetEntity(0));
    int index = -5;
    std::string entityString1 = "";
    EXPECT_EQ(entityString1, skills.GetEntity(index));
    EXPECT_EQ(actionString, skills.GetAction(0));
    EXPECT_EQ(entityString1, skills.GetAction(index));
    EXPECT_EQ(authorityString, skills.GetAuthority(0));
    EXPECT_EQ(entityString1, skills.GetAuthority(index));
    EXPECT_EQ(schemeString, skills.GetScheme(0));
    EXPECT_EQ(entityString1, skills.GetScheme(index));
    EXPECT_EQ(pathString, skills.GetPath(0));
    EXPECT_EQ(entityString1, skills.GetPath(index));
    EXPECT_EQ(schemeSpecificPartsString, skills.GetSchemeSpecificPart(0));
    EXPECT_EQ(entityString1, skills.GetSchemeSpecificPart(index));
    EXPECT_EQ(typeString, skills.GetType(0));
}

/**
 * @tc.number: AaFwk_Skills_addremoveType_0100
 * @tc.name: addType(PatternsMatcher)/ removeType(PatternsMatcher)
 * @tc.desc: Verify addType/removeType result.
 */
HWTEST_F(SkillsBaseTest, AaFwk_Skills_addremoveType_0100, Function | MediumTest | Level1)
{
    std::string patternStr = std::string("systems/*t");

    PatternsMatcher pattern(patternStr, MatchType::DEFAULT);

    base_->AddType(pattern);
    std::string type1 = base_->GetType(0);
    EXPECT_EQ(patternStr, type1);

    base_->RemoveType(patternStr);

    EXPECT_EQ(0, base_->CountEntities());

    base_->AddType(pattern);

    std::string patternStr2 = std::string("systems/*test");
    PatternsMatcher pattern2(patternStr2, MatchType::PREFIX);
    base_->AddType(pattern2);
    std::string type2 = base_->GetType(1);
    EXPECT_EQ(patternStr2, type2);

    base_->RemoveType(pattern2);
    EXPECT_EQ(0, base_->CountEntities());

    std::string patternStr3 = std::string("systems/*test3");
    base_->AddType(patternStr3, MatchType::GLOBAL);

    std::string type3 = base_->GetType(1);
    EXPECT_EQ(patternStr3, type3);

    std::string patternStr4 = std::string("");
    std::string type4 = base_->GetType(-5);
    EXPECT_EQ(patternStr4, type4);

    base_->RemoveType(patternStr3, MatchType::GLOBAL);

    EXPECT_EQ(0, base_->CountEntities());
}

/**
 * @tc.number: AaFwk_Skills_MatchData_0100
 * @tc.name: MatchData
 * @tc.desc: Test MatchData.
 * @tc.require: issueI648W6
 */
HWTEST_F(SkillsBaseTest, AaFwk_Skills_MatchData_0100, Function | MediumTest | Level1)
{
    std::string type = "this is type";
    std::string scheme = "this is scheme";
    std::string value = "this is value";
    OHOS::Uri data(value);
    int result = base_->MatchData(type, scheme, data);
    EXPECT_EQ(result, DISMATCH_DATA);
}

/**
 * @tc.number: AaFwk_Skills_MatchData_0200
 * @tc.name: MatchData
 * @tc.desc: Test MatchData.
 * @tc.require: issueI648W6
 */
HWTEST_F(SkillsBaseTest, AaFwk_Skills_MatchData_0200, Function | MediumTest | Level1)
{
    std::string type = "";
    std::string scheme = "";
    std::string value = "this is value";
    OHOS::Uri data(value);
    int result = base_->MatchData(type, scheme, data);
    EXPECT_EQ(result, DISMATCH_TYPE);
}

/**
 * @tc.number: AaFwk_Skills_MatchData_0300
 * @tc.name: MatchData
 * @tc.desc: Test MatchData.
 * @tc.require: issueI648W6
 */
HWTEST_F(SkillsBaseTest, AaFwk_Skills_MatchData_0300, Function | MediumTest | Level1)
{
    std::string type = "this is type";
    std::string scheme = "this is scheme";
    std::string value = "this is value";
    OHOS::Uri data(value);
    std::string pattern = "this is pattern";
    PatternsMatcherIn_ = std::make_shared<PatternsMatcher>(pattern, MatchType::DEFAULT);
    std::string ret = PatternsMatcherIn_->GetPattern();
    EXPECT_EQ(ret, pattern);
    base_->AddScheme("12345");
    int result = base_->MatchData(type, scheme, data);
    EXPECT_EQ(result, DISMATCH_DATA);
}

/**
 * @tc.number: AaFwk_Skills_FindMimeType_0100
 * @tc.name: FindMimeType
 * @tc.desc: Test FindMimeType.
 * @tc.require: issueI653GZ
 */
HWTEST_F(SkillsBaseTest, AaFwk_Skills_FindMimeType_0100, Function | MediumTest | Level1)
{
    std::string type = "";
    bool result = base_->FindMimeType(type);
    EXPECT_EQ(result, false);

    std::string type1 = "this is type";
    bool result1 = base_->FindMimeType(type1);
    EXPECT_EQ(result1, false);
}

/**
 * @tc.number: AaFwk_Skills_FindMimeType_0200
 * @tc.name: FindMimeType
 * @tc.desc: Test FindMimeType.
 * @tc.require: issue
 */
HWTEST_F(SkillsBaseTest, AaFwk_Skills_FindMimeType_0200, Function | MediumTest | Level1)
{
    std::string empty;
    std::string type = "*/*";
    int typeCount = 1;

    for (int i = 0; i < SET_COUNT; i++) {
        base_->AddType(type);
    }
    EXPECT_EQ(typeCount, base_->CountTypes());

    PatternsMatcherIn_ = std::make_shared<PatternsMatcher>(type, MatchType::DEFAULT);
    std::string ret = PatternsMatcherIn_->GetPattern();
    EXPECT_EQ(ret, type);
    bool result = base_->FindMimeType(type);
    EXPECT_EQ(result, true);
}

/**
 * @tc.number: AaFwk_Skills_FindMimeType_0300
 * @tc.name: FindMimeType
 * @tc.desc: Test FindMimeType.
 * @tc.require: issue
 */
HWTEST_F(SkillsBaseTest, AaFwk_Skills_FindMimeType_0300, Function | MediumTest | Level1)
{
    std::string empty;
    std::string type = "type/system.test";
    int typeCount = 1;

    for (int i = 0; i < SET_COUNT; i++) {
        base_->AddType(type);
    }
    EXPECT_EQ(typeCount, base_->CountTypes());

    PatternsMatcherIn_ = std::make_shared<PatternsMatcher>(type, MatchType::DEFAULT);
    std::string ret = PatternsMatcherIn_->GetPattern();
    EXPECT_EQ(ret, type);
    bool result = base_->FindMimeType(type);
    EXPECT_EQ(result, true);
    EXPECT_EQ(true, base_->HasType(type));
    EXPECT_EQ(type, base_->GetType(0));

    base_->RemoveType(type);
    EXPECT_EQ(0, base_->CountTypes());
    EXPECT_EQ(false, base_->FindMimeType(type));
}

/**
 * @tc.number: AaFwk_Skills_RegionMatches_0100
 * @tc.name: RegionMatches
 * @tc.desc: Test RegionMatches.
 * @tc.require: issueI653GZ
 */
HWTEST_F(SkillsBaseTest, AaFwk_Skills_RegionMatches_0100, Function | MediumTest | Level1)
{
    std::string type = "this is type";
    int toffset = -1;
    std::string other = "this is other";
    int ooffset = -2;
    int len = 1;
    bool result = base_->RegionMatches(type, toffset, other, ooffset, len);
    EXPECT_EQ(result, false);
}

/**
 * @tc.number: AaFwk_Skills_RegionMatches_0200
 * @tc.name: RegionMatches
 * @tc.desc: Test RegionMatches.
 * @tc.require: issueI653GZ
 */
HWTEST_F(SkillsBaseTest, AaFwk_Skills_RegionMatches_0200, Function | MediumTest | Level1)
{
    std::string type = "this is type";
    int toffset = 1;
    std::string other = "this is other";
    int ooffset = 2;
    int len = 2;
    bool result = base_->RegionMatches(type, toffset, other, ooffset, len);
    EXPECT_EQ(result, false);

    int len1 = 0;
    bool result1 = base_->RegionMatches(type, toffset, other, ooffset, len1);
    EXPECT_EQ(result1, true);
}

/**
 * @tc.number: AaFwk_Skills_RegionMatches_0300
 * @tc.name: RegionMatches
 * @tc.desc: Test RegionMatches.
 * @tc.require: issueI653GZ
 */
HWTEST_F(SkillsBaseTest, AaFwk_Skills_RegionMatches_0300, Function | MediumTest | Level1)
{
    std::string type = "this is type";
    int toffset = 1;
    std::string other = "this is other";
    int ooffset = -2;
    int len = 20;
    bool result = base_->RegionMatches(type, toffset, other, ooffset, len);
    EXPECT_EQ(result, false);
}

/**
 * @tc.number: AaFwk_Skills_MatchEntities_0200
 * @tc.name: MatchEntities
 * @tc.desc: Test MatchEntities.
 * @tc.require: issue
 */
HWTEST_F(SkillsBaseTest, AaFwk_Skills_MatchEntities_0200, Function | MediumTest | Level1)
{
    std::vector<std::string> entities;
    std::string ret = "";
    std::string result = base_->MatchEntities(entities);
    EXPECT_EQ(result, ret);
}

using testParamsType = std::tuple<std::string, std::string>;
class SkillsParamsTest : public testing::TestWithParam<testParamsType> {
public:
    SkillsParamsTest()
    {}
    ~SkillsParamsTest()
    {}
    static void SetUpTestCase(void);
    static void TearDownTestCase(void);
    void SetUp();
    void TearDown();
    std::shared_ptr<Skills> skills_ = nullptr;
};

void SkillsParamsTest::SetUpTestCase(void)
{}

void SkillsParamsTest::TearDownTestCase(void)
{}

void SkillsParamsTest::SetUp(void)
{
    skills_ = std::make_shared<Skills>();
}

void SkillsParamsTest::TearDown(void)
{}

/**
 * @tc.number: AaFwk_Skills_Params_0100
 * @tc.name: SetWantParams/GetWantParams
 * @tc.desc: Verify addType/removeType result.
 */
HWTEST_P(SkillsParamsTest, AaFwk_Skills_Params_0100, Function | MediumTest | Level1)
{
    std::string keyStr = std::get<0>(GetParam());
    std::string valueStr = std::get<1>(GetParam());
    WantParams wantParams;
    wantParams.SetParam(keyStr, String::Box(valueStr));
    skills_->SetWantParams(wantParams);
    EXPECT_EQ(valueStr, String::Unbox(IString::Query(skills_->GetWantParams().GetParam(keyStr))));
}

INSTANTIATE_TEST_SUITE_P(SkillsParamsTestCaseP, SkillsParamsTest,
    testing::Values(testParamsType("", "asdsdsdasa"), testParamsType(std::string(LARGE_STR_LEN + 1, 's'), "sadsdsdads"),
        testParamsType("#$%^&*(!@\":<>{}", "asdsdsdasa"), testParamsType("3456677", ""),
        testParamsType("1234", std::string(LARGE_STR_LEN + 1, 's')),
        testParamsType("2323sdasdZ", "#$%^&*(!@\":<>{}sadsdasdsaf"), testParamsType("12345667", "sdasdfdsffdgfdg"),
        testParamsType("", ""),
        testParamsType(std::string(LARGE_STR_LEN + 1, 'k'), std::string(LARGE_STR_LEN + 1, 'k')),
        testParamsType("#$%^&*(!@\":<>{},/", "#$%^&*(!@\":<>{},/")));
}  // namespace AAFwk
}  // namespace OHOS