/*
 * Copyright (C) 2021-2024 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 "sms_persist_helper.h"

#include <sstream>
#include "ability_manager_interface.h"
#include "if_system_ability_manager.h"
#include "iservice_registry.h"
#include "parameter.h"
#include "phonenumbers/phonenumber.pb.h"
#include "resource_manager.h"
#include "string_utils.h"
#include "system_ability.h"
#include "system_ability_definition.h"
#include "telephony_errors.h"
#include "telephony_log_wrapper.h"


namespace OHOS {
namespace Telephony {
constexpr static uint8_t SMS_TYPE_CDMA = 2;
const std::string SMS_URI = "datashare:///com.ohos.smsmmsability";
const std::string SMS_SUBSECTION = "datashare:///com.ohos.smsmmsability/sms_mms/sms_subsection";
const std::string SMS_MMS_INFO = "datashare:///com.ohos.smsmmsability/sms_mms/sms_mms_info";
const std::string SMS_SESSION = "datashare:///com.ohos.smsmmsability/sms_mms/session";
const std::string CONTACT_URI = "datashare:///com.ohos.contactsdataability";
const std::string CONTACT_BLOCK = "datashare:///com.ohos.contactsdataability/contacts/contact_blocklist";
const std::string CONTACT_DATA = "datashare:///com.ohos.contactsdataability/contacts/contact_data";
const std::string RAW_CONTACT = "datashare:///com.ohos.contactsdataability/contacts/raw_contact";
const std::string ISO_COUNTRY_CODE = "CN";
const std::string PHONE_NUMBER = "phone_number";
const std::string DETAIL_INFO = "detail_info";
const std::string TYPE_ID = "type_id";
std::string g_id = "id";
const std::string RAW_CONTACT_ID = "raw_contact_id";
const std::string CONTACTED_COUNT = "contacted_count";
const std::string LASTEST_CONTACTED_TIME = "lastest_contacted_time";
constexpr static uint8_t TYPE_ID_VALUE = 5;
const std::string PREFIX = "+86";
const std::string NUMBER_START_STR = "192";
constexpr uint32_t EVENT_RELEASE_DATA_SHARE_HELPER = 10000;
constexpr int64_t RELEASE_DATA_SHARE_HELPER_TIMEOUT = 5000;

static std::shared_ptr<AppExecFwk::EventRunner> smsPersistHelperEventRunner_ =
    AppExecFwk::EventRunner::Create("SmsPersistHelper");
SmsPersistHelper::SmsPersistHelper() : AppExecFwk::EventHandler(smsPersistHelperEventRunner_) {}

SmsPersistHelper::~SmsPersistHelper() {}

std::shared_ptr<DataShare::DataShareHelper> SmsPersistHelper::CreateSmsHelper()
{
    std::lock_guard<ffrt::mutex> lock(mutex_);
    RemoveEvent(EVENT_RELEASE_DATA_SHARE_HELPER);
    SendEvent(EVENT_RELEASE_DATA_SHARE_HELPER, 0, RELEASE_DATA_SHARE_HELPER_TIMEOUT);
    if (smsDataShareHelper_ == nullptr) {
        smsDataShareHelper_ = CreateDataShareHelper(SMS_URI);
    }
    return smsDataShareHelper_;
}

std::shared_ptr<DataShare::DataShareHelper> SmsPersistHelper::CreateDataShareHelper(const std::string &uri)
{
    auto saManager = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
    if (saManager == nullptr) {
        TELEPHONY_LOGE(" Get system ability mgr failed.");
        return nullptr;
    }
    auto remoteObj = saManager->GetSystemAbility(TELEPHONY_SMS_MMS_SYS_ABILITY_ID);
    if (remoteObj == nullptr) {
        TELEPHONY_LOGE("GetSystemAbility Service Failed.");
        return nullptr;
    }
    return DataShare::DataShareHelper::Creator(remoteObj, uri);
}

bool SmsPersistHelper::Insert(DataShare::DataShareValuesBucket &values, int32_t &dataBaseId)
{
    std::shared_ptr<DataShare::DataShareHelper> helper = CreateSmsHelper();
    if (helper == nullptr) {
        TELEPHONY_LOGE("Create Data Ability Helper nullptr Failed.");
        return false;
    }
    Uri uri(SMS_SUBSECTION);
    int ret = helper->Insert(uri, values);
    dataBaseId = ret;
    TELEPHONY_LOGI("Insert result: %{public}d.", ret);
    return ret >= 0 ? true : false;
}

bool SmsPersistHelper::Insert(std::string tableUri, DataShare::DataShareValuesBucket &values)
{
    std::shared_ptr<DataShare::DataShareHelper> helper = CreateSmsHelper();
    if (helper == nullptr) {
        TELEPHONY_LOGE("Create Data Ability Helper nullptr Failed.");
        return false;
    }
    Uri uri(tableUri);
    int ret = helper->Insert(uri, values);
    TELEPHONY_LOGI("Insert result: %{public}d.", ret);
    return ret >= 0 ? true : false;
}

bool SmsPersistHelper::Insert(std::string tableUri, DataShare::DataShareValuesBucket &values, int32_t &id)
{
    std::shared_ptr<DataShare::DataShareHelper> helper = CreateSmsHelper();
    if (helper == nullptr) {
        TELEPHONY_LOGE("Create Data Ability Helper nullptr Failed.");
        return false;
    }
    Uri uri(tableUri);
    int ret = helper->Insert(uri, values);
    id = ret;
    TELEPHONY_LOGI("Insert result: %{public}d.", ret);
    return ret >= 0;
}

bool SmsPersistHelper::IsSameFormatPhoneNumber(const std::string &phoneNum, const std::string &telephone,
    i18n::phonenumbers::PhoneNumberUtil::PhoneNumberFormat format)
{
    std::string formatPhoneNum;
    std::string formatTelephone;
    FormatSmsNumber(phoneNum, ISO_COUNTRY_CODE, format, formatPhoneNum);
    FormatSmsNumber(telephone, ISO_COUNTRY_CODE, format, formatTelephone);
    return formatPhoneNum == formatTelephone;
}

bool SmsPersistHelper::QueryOneSessionByPhoneNum(DataShare::DataSharePredicates &predicates,
    uint16_t &sessionId, uint16_t &messageCount, const std::string &phoneNum)
{
    std::shared_ptr<DataShare::DataShareHelper> helper = CreateSmsHelper();
    if (helper == nullptr) {
        TELEPHONY_LOGE("Create Data Ability Helper nullptr Failed.");
        return false;
    }
    Uri uri(SMS_SESSION);
    std::vector<std::string> columns;
    auto resultSet = helper->Query(uri, predicates, columns);
    if (resultSet == nullptr) {
        TELEPHONY_LOGE("Query Result Set nullptr Failed.");
        return false;
    }
    int32_t result = resultSet->GoToFirstRow();
    int32_t columnInt;
    std::string columnString;
    int columnIndex;
    std::string telephone = "";
    while (result == DataShare::E_OK) {
        resultSet->GetColumnIndex("telephone", columnIndex);
        if (resultSet->GetString(columnIndex, columnString) == 0) {
            telephone = columnString;
        }
        if (!IsSameFormatPhoneNumber(phoneNum, telephone,
            i18n::phonenumbers::PhoneNumberUtil::PhoneNumberFormat::NATIONAL) && !IsSameFormatPhoneNumber(phoneNum,
            telephone, i18n::phonenumbers::PhoneNumberUtil::PhoneNumberFormat::E164)) {
            TELEPHONY_LOGI("QueryOneSessionByPhoneNum not same format phone number");
            result = resultSet->GoToNextRow();
            continue;
        }
        resultSet->GetColumnIndex("id", columnIndex);
        if (resultSet->GetInt(columnIndex, columnInt) == 0) {
            sessionId = static_cast<uint16_t>(columnInt);
        }
        resultSet->GetColumnIndex("message_count", columnIndex);
        if (resultSet->GetInt(columnIndex, columnInt) == 0) {
            messageCount = static_cast<uint16_t>(columnInt);
            resultSet->Close();
            return true;
        }
        break;
    }
    resultSet->Close();
    return false;
}

bool SmsPersistHelper::UpdateSms(DataShare::DataSharePredicates &predicates, DataShare::DataShareValuesBucket &values)
{
    std::shared_ptr<DataShare::DataShareHelper> helper = CreateSmsHelper();
    if (helper == nullptr) {
        TELEPHONY_LOGE("Create Data Ability Helper nullptr Failed.");
        return false;
    }
    Uri uri(SMS_MMS_INFO);
    int ret = helper->Update(uri, predicates, values);
    TELEPHONY_LOGI("UpdateSms result: %{public}d.", ret);
    return ret >= 0;
}

bool SmsPersistHelper::QuerySmsMmsForId(DataShare::DataSharePredicates &predicates, int32_t &dataBaseId)
{
    std::shared_ptr<DataShare::DataShareHelper> helper = CreateSmsHelper();
    if (helper == nullptr) {
        TELEPHONY_LOGE("Create Data Ability Helper nullptr Failed.");
        return false;
    }
    Uri uri(SMS_MMS_INFO);
    std::vector<std::string> columns;
    auto resultSet = helper->Query(uri, predicates, columns);
    if (resultSet == nullptr) {
        TELEPHONY_LOGE("Query Result Set nullptr Failed.");
        return false;
    }
    resultSet->GoToFirstRow();
    int32_t columnInt;
    int columnIndex;
    resultSet->GetColumnIndex(SmsMmsInfo::MSG_ID, columnIndex);
    if (resultSet->GetInt(columnIndex, columnInt) == 0) {
        dataBaseId = columnInt;
    }
    resultSet->Close();
    return true;
}

bool SmsPersistHelper::Update(DataShare::DataSharePredicates &predicates, DataShare::DataShareValuesBucket &values)
{
    std::shared_ptr<DataShare::DataShareHelper> helper = CreateSmsHelper();
    if (helper == nullptr) {
        TELEPHONY_LOGE("Create Data Ability Helper nullptr Failed.");
        return false;
    }
    Uri uri(SMS_SESSION);
    int ret = helper->Update(uri, predicates, values);
    TELEPHONY_LOGI("Update result: %{public}d.", ret);
    return ret >= 0 ? true : false;
}

bool SmsPersistHelper::Query(DataShare::DataSharePredicates &predicates, std::vector<SmsReceiveIndexer> &indexers)
{
    std::shared_ptr<DataShare::DataShareHelper> helper = CreateSmsHelper();
    if (helper == nullptr) {
        TELEPHONY_LOGE("Create Data Ability Helper nullptr Failed.");
        return false;
    }
    Uri uri(SMS_SUBSECTION);
    std::vector<std::string> columns;
    auto resultSet = helper->Query(uri, predicates, columns);
    if (resultSet == nullptr) {
        TELEPHONY_LOGE("Query Result Set nullptr Failed.");
        return false;
    }

    int resultSetNum = resultSet->GoToFirstRow();
    TELEPHONY_LOGE("resultSetNum is %{public}d before cycle", resultSetNum);
    while (resultSetNum == 0) {
        SmsReceiveIndexer indexer;
        ResultSetConvertToIndexer(indexer, resultSet);
        indexers.push_back(indexer);
        resultSetNum = resultSet->GoToNextRow();
        TELEPHONY_LOGE("resultSetNum is %{public}d in cycle", resultSetNum);
    }
    resultSet->Close();
    return true;
}

bool SmsPersistHelper::QueryMaxGroupId(DataShare::DataSharePredicates &predicates, uint16_t &maxGroupId)
{
    std::shared_ptr<DataShare::DataShareHelper> helper = CreateSmsHelper();
    if (helper == nullptr) {
        TELEPHONY_LOGE("Create Data Ability Helper nullptr Failed.");
        return false;
    }
    Uri uri(SMS_MMS_INFO);
    std::vector<std::string> columns;
    auto resultSet = helper->Query(uri, predicates, columns);
    if (resultSet == nullptr) {
        TELEPHONY_LOGE("Query Result Set nullptr Failed.");
        return false;
    }

    int32_t columnInt;
    int columnIndex;
    resultSet->GoToLastRow();
    resultSet->GetColumnIndex(SmsMmsInfo::GROUP_ID, columnIndex);
    if (resultSet->GetInt(columnIndex, columnInt) == 0) {
        maxGroupId = columnInt;
    }
    resultSet->Close();
    return true;
}

bool SmsPersistHelper::Delete(DataShare::DataSharePredicates &predicates)
{
    std::shared_ptr<DataShare::DataShareHelper> helper = CreateSmsHelper();
    if (helper == nullptr) {
        TELEPHONY_LOGE("Create Data Ability Helper nullptr Failed.");
        return false;
    }
    Uri uri(SMS_SUBSECTION);
    int ret = helper->Delete(uri, predicates);
    TELEPHONY_LOGI("Delete result: %{public}d.", ret);
    return ret >= 0 ? true : false;
}

bool SmsPersistHelper::QueryBlockPhoneNumber(const std::string &phoneNum)
{
    bool result = false;
    if (phoneNum.empty()) {
        return result;
    }
    return result;
}

int32_t SmsPersistHelper::FormatSmsNumber(const std::string &num, std::string countryCode,
    const i18n::phonenumbers::PhoneNumberUtil::PhoneNumberFormat formatInfo, std::string &formatNum)
{
    if (num.empty()) {
        TELEPHONY_LOGE("num is nullptr!");
        return TELEPHONY_ERR_ARGUMENT_INVALID;
    }
    i18n::phonenumbers::PhoneNumberUtil *phoneUtils = i18n::phonenumbers::PhoneNumberUtil::GetInstance();
    if (phoneUtils == nullptr) {
        TELEPHONY_LOGE("phoneUtils is nullptr");
        return TELEPHONY_ERR_LOCAL_PTR_NULL;
    }
    transform(countryCode.begin(), countryCode.end(), countryCode.begin(), ::toupper);
    i18n::phonenumbers::PhoneNumber parseResult;
    phoneUtils->Parse(num, countryCode, &parseResult);
    if (phoneUtils->IsValidNumber(parseResult)) {
        phoneUtils->Format(parseResult, formatInfo, &formatNum);
    } else {
        std::string numTemp = "";
        numTemp.assign(num);
        CbnFormat(numTemp, formatInfo, formatNum);
    }
    if (formatNum.empty() || formatNum == "0") {
        return TELEPHONY_ERROR;
    }
    TrimSpace(formatNum);
    return TELEPHONY_SUCCESS;
}

void SmsPersistHelper::CbnFormat(std::string &numTemp,
    const i18n::phonenumbers::PhoneNumberUtil::PhoneNumberFormat formatInfo, std::string &formatNum)
{
    TELEPHONY_LOGD("into CbnFormat");
    uint8_t minLength = 3;
    if (numTemp.size() < minLength) {
        TELEPHONY_LOGD("Phonenumber is too short");
        return;
    }
    if (numTemp.substr(0, NUMBER_START_STR.size()) == NUMBER_START_STR ||
        numTemp.substr(PREFIX.size(), NUMBER_START_STR.size()) == NUMBER_START_STR) {
        if (formatInfo == i18n::phonenumbers::PhoneNumberUtil::PhoneNumberFormat::NATIONAL) {
            if (numTemp.substr(0, PREFIX.size()) == PREFIX) {
                numTemp.erase(0, PREFIX.size());
                formatNum.assign(numTemp);
                return;
            }
            formatNum.assign(numTemp);
            return;
        }
        if (formatInfo == i18n::phonenumbers::PhoneNumberUtil::PhoneNumberFormat::INTERNATIONAL) {
            if (numTemp.substr(0, PREFIX.size()) == PREFIX) {
                formatNum.assign(numTemp);
                return;
            }
            formatNum.assign(PREFIX + numTemp);
        }
    }
}

void SmsPersistHelper::TrimSpace(std::string &num)
{
    std::string word;
    std::stringstream streamNum(num);
    std::string store;
    while (streamNum >> word) {
        store += word;
    }
    num = store;
}

bool SmsPersistHelper::UpdateContact(const std::string &address)
{
    bool result = false;
    if (address.empty()) {
        TELEPHONY_LOGE("address empty");
        return result;
    }
    int32_t rawCountId = 0;
    int32_t contactedCount = 0;
    bool ret = QueryContactedCount(address, rawCountId, contactedCount);
    if (!ret) {
        TELEPHONY_LOGE("get contacted count fail");
        return result;
    }
    TELEPHONY_LOGI("rawCountId:%{public}d, contactedCount:%{public}d", rawCountId, contactedCount);
    std::shared_ptr<DataShare::DataShareHelper> helper = CreateDataShareHelper(CONTACT_URI);
    if (helper == nullptr) {
        TELEPHONY_LOGE("Create Data Ability Helper nullptr Failed.");
        return false;
    }
    std::time_t timep;
    int64_t currentTime = time(&timep);
    Uri uri(RAW_CONTACT);
    DataShare::DataSharePredicates predicates;
    predicates.EqualTo(g_id, rawCountId);
    DataShare::DataShareValuesBucket bucket;
    bucket.Put(CONTACTED_COUNT, contactedCount + 1);
    bucket.Put(LASTEST_CONTACTED_TIME, std::to_string(currentTime));
    auto updateValue = helper->Update(uri, predicates, bucket);
    TELEPHONY_LOGI("updateValue:%{public}d", updateValue);
    helper->Release();
    return updateValue >= 0 ? true : false;
}

bool SmsPersistHelper::QueryContactedCount(const std::string &address, int32_t &rawCountId, int32_t &contactedCount)
{
    bool ret = QueryRawContactId(address, rawCountId);
    if (!ret) {
        TELEPHONY_LOGE("no sms address in contact");
        return ret;
    }
    std::shared_ptr<DataShare::DataShareHelper> helper = CreateDataShareHelper(CONTACT_URI);
    if (helper == nullptr) {
        TELEPHONY_LOGE("Create Data Ability Helper nullptr Failed.");
        return false;
    }
    Uri uri(RAW_CONTACT);
    std::vector<std::string> columns;
    DataShare::DataSharePredicates predicates;
    predicates.EqualTo(g_id, rawCountId);
    auto resultSet = helper->Query(uri, predicates, columns);
    bool result = false;
    if (resultSet == nullptr) {
        TELEPHONY_LOGE("result set nullptr.");
        helper->Release();
        return result;
    }
    int32_t count = 0;
    if (resultSet->GetRowCount(count) == 0 && count != 0) {
        resultSet->GoToFirstRow();
        int columnIndex;
        resultSet->GetColumnIndex(CONTACTED_COUNT, columnIndex);
        if (resultSet->GetInt(columnIndex, contactedCount) == 0) {
            result = true;
        }
    }
    resultSet->Close();
    helper->Release();
    return result;
}

bool SmsPersistHelper::QueryRawContactId(const std::string &address, int32_t &rawCountId)
{
    std::shared_ptr<DataShare::DataShareHelper> helper = CreateDataShareHelper(CONTACT_URI);
    if (helper == nullptr) {
        TELEPHONY_LOGE("Create Data Ability Helper nullptr Failed.");
        return false;
    }
    Uri uri(CONTACT_DATA);
    std::vector<std::string> columns;
    DataShare::DataSharePredicates predicates;
    std::string nationalNum;
    std::string internationalNum;
    int32_t ret = FormatSmsNumber(
        address, ISO_COUNTRY_CODE, i18n::phonenumbers::PhoneNumberUtil::PhoneNumberFormat::NATIONAL, nationalNum);
    if (ret != TELEPHONY_SUCCESS) {
        TELEPHONY_LOGE("Phone Number format Failed.");
        nationalNum = address;
    }
    ret = FormatSmsNumber(address, ISO_COUNTRY_CODE,
        i18n::phonenumbers::PhoneNumberUtil::PhoneNumberFormat::INTERNATIONAL, internationalNum);
    if (ret != TELEPHONY_SUCCESS) {
        TELEPHONY_LOGE("Phone Number format Failed.");
        internationalNum = address;
    }
    predicates.EqualTo(DETAIL_INFO, nationalNum)->Or()->EqualTo(DETAIL_INFO, internationalNum);
    predicates.EqualTo(TYPE_ID, TYPE_ID_VALUE);
    auto resultSet = helper->Query(uri, predicates, columns);
    bool result = false;
    if (resultSet == nullptr) {
        TELEPHONY_LOGE("result set nullptr.");
        helper->Release();
        return result;
    }
    int32_t count = 0;
    if (resultSet->GetRowCount(count) == 0 && count != 0) {
        resultSet->GoToFirstRow();
        int columnIndex;
        resultSet->GetColumnIndex(RAW_CONTACT_ID, columnIndex);
        if (resultSet->GetInt(columnIndex, rawCountId) == 0) {
            result = true;
        }
    }
    resultSet->Close();
    helper->Release();
    return result;
}

bool SmsPersistHelper::QueryParamBoolean(const std::string key, bool defValue)
{
    const int PARAM_SIZE = 64;
    char paramOutBuff[PARAM_SIZE] = { 0 };
    std::string defStrValue = defValue ? "1" : "0";
    std::string paramValue(defStrValue);

    int retLen = GetParameter(key.c_str(), defStrValue.c_str(), paramOutBuff, PARAM_SIZE);
    if (retLen > 0) {
        paramOutBuff[retLen] = '\0';
        paramValue.assign(paramOutBuff, retLen);
    }

    TELEPHONY_LOGI("QueryParamBoolean: %{public}zu : %{public}s", paramValue.size(), paramValue.c_str());
    if ((paramValue == std::string("1")) || (paramValue == std::string("y")) || (paramValue == std::string("yes")) ||
        (paramValue == std::string("on")) || (paramValue == std::string("true"))) {
        return true;
    } else if ((paramValue == std::string("0")) || (paramValue == std::string("n")) ||
               (paramValue == std::string("no")) || (paramValue == std::string("off")) ||
               (paramValue == std::string("false"))) {
        return false;
    }
    return defValue;
}

void SmsPersistHelper::ConvertIntToIndexer(
    SmsReceiveIndexer &info, const std::shared_ptr<DataShare::DataShareResultSet> &resultSet)
{
    int32_t columnInt;
    int columnIndex;
    resultSet->GetColumnIndex(SmsSubsection::FORMAT, columnIndex);
    if (resultSet->GetInt(columnIndex, columnInt) == 0) {
        info.SetIsCdma(columnInt == SMS_TYPE_CDMA);
    }

    resultSet->GetColumnIndex(SmsSubsection::SMS_SUBSECTION_ID, columnIndex);
    if (resultSet->GetInt(columnIndex, columnInt) == 0) {
        info.SetMsgRefId(columnInt);
    }

    resultSet->GetColumnIndex(SmsSubsection::SIZE, columnIndex);
    if (resultSet->GetInt(columnIndex, columnInt) == 0) {
        info.SetMsgCount(columnInt);
    }

    resultSet->GetColumnIndex(SmsSubsection::SUBSECTION_INDEX, columnIndex);
    if (resultSet->GetInt(columnIndex, columnInt) == 0) {
        info.SetMsgSeqId(columnInt);
    }

    resultSet->GetColumnIndex(SmsSubsection::DEST_PORT, columnIndex);
    if (resultSet->GetInt(columnIndex, columnInt) == 0) {
        info.SetDestPort(columnInt);
    }

    resultSet->GetColumnIndex(SmsSubsection::ID, columnIndex);
    if (resultSet->GetInt(columnIndex, columnInt) == 0) {
        info.SetDataBaseId(columnInt);
    }
}

void SmsPersistHelper::ConvertStringToIndexer(
    SmsReceiveIndexer &info, const std::shared_ptr<DataShare::DataShareResultSet> &resultSet)
{
    int columnIndex;
    std::string columnValue;
    resultSet->GetColumnIndex(SmsSubsection::RECEIVER_NUMBER, columnIndex);
    if (resultSet->GetString(columnIndex, columnValue) == 0) {
        info.SetVisibleAddress(columnValue);
    }
    resultSet->GetColumnIndex(SmsSubsection::SENDER_NUMBER, columnIndex);
    if (resultSet->GetString(columnIndex, columnValue) == 0) {
        info.SetOriginatingAddress(columnValue);
    }
    resultSet->GetColumnIndex(SmsSubsection::START_TIME, columnIndex);
    if (resultSet->GetString(columnIndex, columnValue) == 0) {
        std::istringstream str(columnValue);
        int64_t columnValueInt64 = 0;
        str >> columnValueInt64;
        info.SetTimestamp(columnValueInt64);
    }
    resultSet->GetColumnIndex(SmsSubsection::END_TIME, columnIndex);
    if (resultSet->GetString(columnIndex, columnValue) == 0) {
        std::istringstream str(columnValue);
        int64_t columnValueInt64 = 0;
        str >> columnValueInt64;
        info.SetTimestamp(columnValueInt64);
    }
    resultSet->GetColumnIndex(SmsSubsection::REW_PUD, columnIndex);
    if (resultSet->GetString(columnIndex, columnValue) == 0) {
        info.SetPdu(StringUtils::HexToByteVector(columnValue));
    }
}

void SmsPersistHelper::ResultSetConvertToIndexer(
    SmsReceiveIndexer &info, const std::shared_ptr<DataShare::DataShareResultSet> &resultSet)
{
    ConvertIntToIndexer(info, resultSet);
    ConvertStringToIndexer(info, resultSet);
}

void SmsPersistHelper::ProcessEvent(const AppExecFwk::InnerEvent::Pointer &event)
{
    if (event->GetInnerEventId() == EVENT_RELEASE_DATA_SHARE_HELPER) {
        ReleaseDataShareHelper();
    }
}

void SmsPersistHelper::ReleaseDataShareHelper()
{
    std::lock_guard<ffrt::mutex> lock(mutex_);
    if (smsDataShareHelper_ != nullptr) {
        smsDataShareHelper_->Release();
    }
    smsDataShareHelper_ = nullptr;
}
} // namespace Telephony
} // namespace OHOS