1/*
2 *Copyright (c) 2022 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 *     http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16#include "statistics_ability.h"
17
18#include <algorithm>
19#include <iomanip>
20#include <iostream>
21#include <map>
22#include <sstream>
23
24#include "wukong_util.h"
25
26namespace OHOS {
27namespace WuKong {
28namespace {
29const uint32_t DECIMAL_LENGTH = 2;
30const float PERCENTAGE = 100.0;
31}
32
33void StatisticsAbility::StatisticsDetail(std::vector<std::map<std::string, std::string>> srcDatas,
34                                         std::map<std::string, std::shared_ptr<Table>> &destTables)
35{
36    SrcDatasPretreatment(srcDatas);
37    std::shared_ptr<AbilityStatisticsRecord> globalAbilityStatisticsRecordPtr =
38        std::make_shared<AbilityStatisticsRecord>();
39    globalAbilityStatisticsRecordPtr->bundleName_ = "total";
40    std::vector<std::string> line;
41    for (auto bundle : abilityStatisticsMsg_) {
42        DEBUG_LOG_STR("start bundlename{%s}", bundle.first.c_str());
43        std::shared_ptr<AbilityStatisticsRecord> curAbilityStatisticsRecordPtr = bundle.second;
44        globalAbilityStatisticsRecordPtr->inputedAbilityCount_ += curAbilityStatisticsRecordPtr->inputedAbilityCount_;
45        globalAbilityStatisticsRecordPtr->abilitiesCount_ += curAbilityStatisticsRecordPtr->abilitiesCount_;
46
47        UpdateLine(curAbilityStatisticsRecordPtr, line);
48        record_.push_back(line);
49    }
50    UpdateLine(globalAbilityStatisticsRecordPtr, line);
51    record_.push_back(line);
52    std::shared_ptr<Table> table = std::make_shared<Table>(headers_, record_);
53    record_.clear();
54    table->SetName("all");
55    table->SetDetail("ability");
56    destTables["all"] = table;
57}
58
59void StatisticsAbility::SrcDatasPretreatment(std::vector<std::map<std::string, std::string>> srcDatas)
60{
61    for (auto srcData : srcDatas) {
62        DEBUG_LOG_STR("bundlename{%s} | abilityName{%s}", srcData["bundleName"].c_str(),
63                      srcData["abilityName"].c_str());
64
65        // check whether bundle is entered resolve create or reuse already exist  StatisticsMsgPtr
66        std::shared_ptr<AbilityStatisticsRecord> curAbilityStatisticsRecordPtr = std::make_shared<AbilityStatisticsRecord>();
67        std::map<std::string, std::shared_ptr<AbilityStatisticsRecord>>::iterator abilityStatisticsRecordIter =
68            abilityStatisticsMsg_.find(srcData["bundleName"]);
69        if (abilityStatisticsRecordIter != abilityStatisticsMsg_.end()) {
70            DEBUG_LOG_STR("use inited curStatisticsMsgPtr by bundleName{%s}", srcData["bundleName"].c_str());
71            curAbilityStatisticsRecordPtr = abilityStatisticsMsg_[srcData["bundleName"]];
72        }
73        curAbilityStatisticsRecordPtr->bundleName_ = srcData["bundleName"];
74        std::vector<std::string>::iterator inputedAbilitiesIter =
75            find(curAbilityStatisticsRecordPtr->inputedAbilities_.begin(),
76                 curAbilityStatisticsRecordPtr->inputedAbilities_.end(), srcData["bundleName"]);
77        if (inputedAbilitiesIter == curAbilityStatisticsRecordPtr->inputedAbilities_.end()) {
78            curAbilityStatisticsRecordPtr->inputedAbilities_.push_back(srcData["bundleName"]);
79        }
80        std::vector<std::string> abilities;
81        WuKongUtil::GetInstance()->GetAllAbilitiesByBundleName(srcData["bundleName"], abilities);
82        DEBUG_LOG_STR("bundleName{%s} all ability size{%d}", srcData["bundleName"].c_str(), abilities.size());
83        curAbilityStatisticsRecordPtr->inputedAbilityCount_ = curAbilityStatisticsRecordPtr->inputedAbilities_.size();
84        if (abilities.size() == 0) {
85            curAbilityStatisticsRecordPtr->abilitiesCount_ = curAbilityStatisticsRecordPtr->inputedAbilities_.size();
86        } else {
87            curAbilityStatisticsRecordPtr->abilitiesCount_ = abilities.size();
88        }
89
90        abilityStatisticsMsg_[srcData["bundleName"]] = curAbilityStatisticsRecordPtr;
91    }
92}
93
94void StatisticsAbility::UpdateLine(std::shared_ptr<AbilityStatisticsRecord> abilityStatisticsRecordPtr,
95                                   std::vector<std::string> &line)
96{
97    std::stringstream bufferStream;
98    std::string bundleName = abilityStatisticsRecordPtr->bundleName_;
99    std::string inputedAbilityCount = std::to_string(abilityStatisticsRecordPtr->inputedAbilityCount_);
100    std::string abilitiesCount = std::to_string(abilityStatisticsRecordPtr->abilitiesCount_);
101    std::string curCoverageStr = "";
102    if (abilityStatisticsRecordPtr->abilitiesCount_ > 0) {
103        float proportion =
104            (abilityStatisticsRecordPtr->inputedAbilityCount_ * PERCENTAGE) / abilityStatisticsRecordPtr->abilitiesCount_;
105        bufferStream.str("");
106        bufferStream << std::setiosflags(std::ios::fixed) << std::setprecision(DECIMAL_LENGTH) << proportion;
107        curCoverageStr = bufferStream.str() + "%";
108    }
109
110    DEBUG_LOG_STR("line content bundleName{%s} | inputedAbilityCount{%s} | abilitiesCount{%s} | curCoverageStr{%s}",
111                  bundleName.c_str(), inputedAbilityCount.c_str(), abilitiesCount.c_str(), curCoverageStr.c_str());
112    line = {bundleName, inputedAbilityCount, abilitiesCount, curCoverageStr};
113}
114
115}  // namespace WuKong
116}  // namespace OHOS
117