/*
 * Copyright (c) 2026 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 <iostream>
#include <string>
#include <ctime>
#include <fstream>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <algorithm>
#include <chrono>
#include <cmath>
#include <libxml/parser.h>
#include "common_utils.h"
#include "testhelper_core.h"
#include "gpx_parser.h"
#include "time_service_client.h"
#include "test_server_client.h"
#include "test_server_error_code.h"
#ifdef ARKXTEST_FONT_ENABLE
#include "rosen_text/font_tool_set.h"
#endif

namespace OHOS::testhelper {
    static bool IsValidTimeFormat(const std::string& timeStr)
    {
        static constexpr size_t idxYearStart = 0;
        static constexpr size_t idxYearEnd = 3;
        static constexpr size_t idxFirstDash = 4;
        static constexpr size_t idxMonthStart = 5;
        static constexpr size_t idxMonthEnd = 6;
        static constexpr size_t idxSecondDash = 7;
        static constexpr size_t idxDayStart = 8;
        static constexpr size_t idxDayEnd = 9;
        static constexpr size_t idxSpace = 10;
        static constexpr size_t idxHourStart = 11;
        static constexpr size_t idxHourEnd = 12;
        static constexpr size_t idxFirstColon = 13;
        static constexpr size_t idxMinuteStart = 14;
        static constexpr size_t idxMinuteEnd = 15;
        static constexpr size_t idxSecondColon = 16;
        static constexpr size_t idxSecStart = 17;
        static constexpr size_t idxSecEnd = 18;

        if (timeStr.length() != timeStrLen) {
            return false;
        }
        auto isDigit = [&timeStr](size_t i) {
            return std::isdigit(static_cast<unsigned char>(timeStr[i]));
        };
        return isDigit(idxYearStart) && isDigit(idxYearStart + 1) &&
               isDigit(idxYearStart + TWO) && isDigit(idxYearEnd) &&
               timeStr[idxFirstDash] == timeSepDash &&
               isDigit(idxMonthStart) && isDigit(idxMonthEnd) &&
               timeStr[idxSecondDash] == timeSepDash &&
               isDigit(idxDayStart) && isDigit(idxDayEnd) &&
               timeStr[idxSpace] == timeSepSpace &&
               isDigit(idxHourStart) && isDigit(idxHourEnd) &&
               timeStr[idxFirstColon] == timeSepColon &&
               isDigit(idxMinuteStart) && isDigit(idxMinuteEnd) &&
               timeStr[idxSecondColon] == timeSepColon &&
               isDigit(idxSecStart) && isDigit(idxSecEnd);
    }

        int32_t TestHelperCore::HandleGetTime()
    {
        LOG_I("HandleGetTime called");
        auto timeService = MiscServices::TimeServiceClient::GetInstance();
        if (!timeService) {
            LOG_E("TimeService not available");
            PrintToConsole("Error: Service is not available.");
            return EXIT_SERVICE_UNAVAILABLE;
        }
        int64_t timeMs = 0;
        timeService->GetWallTimeMs(timeMs);
        time_t seconds = timeMs / MS_PER_SECOND;
        char buffer[TIME_BUFFER_SIZE];
        if (strftime(buffer, TIME_BUFFER_SIZE, "%Y-%m-%d %H:%M:%S", localtime(&seconds)) == 0) {
            LOG_E("strftime failed");
            return EXIT_FAILURE;
        }
        PrintToConsole("Current system time: " + std::string(buffer));
        LOG_I("HandleGetTime completed successfully");
        return EXIT_SUCCESS;
    }

    int32_t TestHelperCore::HandleSetTime(const std::string& timeStr)
    {
        LOG_I("HandleSetTime called with time: %{public}s", timeStr.c_str());
        int64_t timeMs = 0;
        int32_t parseResult = ParseTimeToMs(timeStr, timeMs);
        if (parseResult != PARSE_TIME_SUCCESS) {
            LOG_E("Invalid time: %{public}s", timeStr.c_str());
            if (parseResult == PARSE_TIME_INVALID_FORMAT) {
                PrintToConsole("Error: Invalid time format. Time must be in 'YYYY-MM-DD HH:MM:SS' format.");
            } else if (parseResult == PARSE_TIME_INVALID_VALUE) {
                PrintToConsole("Error: Invalid time value. " + timeStr + " is not a valid date and time.");
            }
            return EXIT_FAILURE;
        }
        auto result = OHOS::testserver::TestServerClient::GetInstance().SetTime(timeMs);
        if (result == OHOS::testserver::TEST_SERVER_OK) {
            PrintToConsole("Set time to " + timeStr + " successfully.");
            LOG_I("HandleSetTime completed successfully");
            return EXIT_SUCCESS;
        } else {
            LOG_E("SetTime failed with error: %{public}d", result);
            PrintToConsole("Error: Service is not available.");
            return EXIT_SERVICE_UNAVAILABLE;
        }
    }

    int32_t TestHelperCore::HandleGetTimezone()
    {
        LOG_I("HandleGetTimezone called");
        auto timeService = MiscServices::TimeServiceClient::GetInstance();
        if (!timeService) {
            LOG_E("TimeService not available");
            PrintToConsole("Error: Service is not available.");
            return EXIT_SERVICE_UNAVAILABLE;
        }
        std::string timezoneId;
        timeService->GetTimeZone(timezoneId);
        PrintToConsole("Current timezone: " + timezoneId);
        LOG_I("HandleGetTimezone completed successfully");
        return EXIT_SUCCESS;
    }

    int32_t TestHelperCore::HandleSetTimezone(const std::string& timezone)
    {
        LOG_I("HandleSetTimezone called with timezone: %{public}s", timezone.c_str());
        auto result = OHOS::testserver::TestServerClient::GetInstance().SetTimezone(timezone);
        if (result == OHOS::testserver::TEST_SERVER_OK) {
            PrintToConsole("Set timezone to " + timezone + " successfully.");
            LOG_I("HandleSetTimezone completed successfully");
            return EXIT_SUCCESS;
        } else if (result == OHOS::testserver::TEST_SERVER_INVALID_TIMEZONE_ID) {
            LOG_E("SetTimezone failed: invalid timezone value");
            PrintToConsole("Error: Invalid timezone value. " + timezone + " is not a valid timezone identifier.");
            return EXIT_FAILURE;
        } else {
            LOG_E("SetTimezone failed with error: %{public}d", result);
            PrintToConsole("Error: Service is not available.");
            return EXIT_SERVICE_UNAVAILABLE;
        }
    }

    bool TestHelperCore::ValidateTimeRanges(int year, int month, int day, int hour, int minute, int second)
    {
        return year >= MIN_YEAR && month >= MIN_MONTH && month <= MAX_MONTH && day >= MIN_DAY &&
               day <= MAX_DAY && hour >= MIN_HOUR && hour <= MAX_HOUR && minute >= MIN_MINUTE &&
               minute <= MAX_MINUTE && second >= MIN_SECOND && second <= MAX_SECOND;
    }

    int32_t TestHelperCore::ParseTimeToMs(const std::string& timeStr, int64_t& timeMs)
    {
        if (!IsValidTimeFormat(timeStr)) {
            return PARSE_TIME_INVALID_FORMAT;
        }
        struct tm originalTimeinfo = {};
        char* result = strptime(timeStr.c_str(), "%Y-%m-%d %H:%M:%S", &originalTimeinfo);
        if (result == nullptr || *result != '\0') {
            return PARSE_TIME_INVALID_VALUE;
        }
        int year = originalTimeinfo.tm_year + BASE_YEAR;
        int month = originalTimeinfo.tm_mon + BASE_MONTH;
        int day = originalTimeinfo.tm_mday;
        int hour = originalTimeinfo.tm_hour;
        int minute = originalTimeinfo.tm_min;
        int second = originalTimeinfo.tm_sec;
        if (!ValidateTimeRanges(year, month, day, hour, minute, second)) {
            return PARSE_TIME_INVALID_VALUE;
        }
        struct tm inputTimeinfo = originalTimeinfo;
        inputTimeinfo.tm_isdst = -1;
        time_t seconds = mktime(&inputTimeinfo);
        if (seconds < 0 || seconds > MAX_TIMESTAMP_SECONDS) {
            return PARSE_TIME_INVALID_VALUE;
        }
        struct tm* convertedTimeinfo = localtime(&seconds);
        if (convertedTimeinfo == nullptr) {
            return PARSE_TIME_INVALID_VALUE;
        }
        if (originalTimeinfo.tm_sec != convertedTimeinfo->tm_sec ||
            originalTimeinfo.tm_min != convertedTimeinfo->tm_min ||
            originalTimeinfo.tm_hour != convertedTimeinfo->tm_hour ||
            originalTimeinfo.tm_mday != convertedTimeinfo->tm_mday ||
            originalTimeinfo.tm_mon != convertedTimeinfo->tm_mon ||
            originalTimeinfo.tm_year != convertedTimeinfo->tm_year) {
            return PARSE_TIME_INVALID_VALUE;
        }
        timeMs = static_cast<int64_t>(seconds) * MS_PER_SECOND;
        return PARSE_TIME_SUCCESS;
    }

    int32_t TestHelperCore::HandleGetPasteData()
    {
        LOG_I("HandleGetPasteData called");
        std::string pasteText;
        auto result = OHOS::testserver::TestServerClient::GetInstance().GetPasteData(pasteText);
        if (result == OHOS::testserver::TEST_SERVER_OK) {
            PrintToConsole("Pasteboard text: " + pasteText);
            LOG_I("HandleGetPasteData completed successfully");
            return EXIT_SUCCESS;
        } else if (result == OHOS::testserver::TEST_SERVER_NOT_SUPPORTED) {
            LOG_E("Pasteboard feature is not supported");
            PrintToConsole("Error: Operation is not supported. Pasteboard is not supported on this device.");
            return EXIT_FAILURE;
        } else {
            LOG_E("GetPasteData failed with error: %{public}d", result);
            PrintToConsole("Error: Service is not available.");
            return EXIT_SERVICE_UNAVAILABLE;
        }
    }

    int32_t TestHelperCore::HandleSetPasteData(const std::string& text)
    {
        LOG_I("HandleSetPasteData called with text length: %{public}zu", text.length());
        
        const size_t MAX_TEXT_SIZE = 128 * 1024 * 1024;
        if (text.length() > MAX_TEXT_SIZE) {
            LOG_E("Text too long: %{public}zu bytes", text.length());
            PrintToConsole("Error: Text is too long. Maximum length is 128MB.");
            return EXIT_FAILURE;
        }
        
        auto result = OHOS::testserver::TestServerClient::GetInstance().SetPasteData(text);
        if (result == OHOS::testserver::TEST_SERVER_OK) {
            PrintToConsole("Pasteboard text set successfully.");
            LOG_I("HandleSetPasteData completed successfully");
            return EXIT_SUCCESS;
        } else if (result == OHOS::testserver::TEST_SERVER_NOT_SUPPORTED) {
            LOG_E("Pasteboard feature is not supported");
            PrintToConsole("Error: Operation is not supported. Pasteboard is not supported on this device.");
            return EXIT_FAILURE;
        } else {
            LOG_E("SetPasteData failed with error: %{public}d", result);
            PrintToConsole("Error: Service is not available.");
            return EXIT_SERVICE_UNAVAILABLE;
        }
    }

    int32_t TestHelperCore::HandleClearPasteData()
    {
        LOG_I("HandleClearPasteData called");
        auto result = OHOS::testserver::TestServerClient::GetInstance().ClearPasteData();
        if (result == OHOS::testserver::TEST_SERVER_OK) {
            PrintToConsole("Pasteboard text cleared successfully.");
            LOG_I("HandleClearPasteData completed successfully");
            return EXIT_SUCCESS;
        } else if (result == OHOS::testserver::TEST_SERVER_NOT_SUPPORTED) {
            LOG_E("Pasteboard feature is not supported");
            PrintToConsole("Error: Operation is not supported. Pasteboard is not supported on this device.");
            return EXIT_FAILURE;
        } else {
            LOG_E("ClearPasteData failed with error: %{public}d", result);
            PrintToConsole("Error: Service is not available.");
            return EXIT_SERVICE_UNAVAILABLE;
        }
    }

    int32_t TestHelperCore::HandleHideKeyboard()
    {
        LOG_I("HandleHideKeyboard called");
        auto result = OHOS::testserver::TestServerClient::GetInstance().HideKeyboard();
        if (result == OHOS::testserver::TEST_SERVER_OK) {
            PrintToConsole("Keyboard hidden successfully.");
            LOG_I("HandleHideKeyboard completed successfully");
            return EXIT_SUCCESS;
        } else if (result == OHOS::testserver::TEST_SERVER_NOT_SUPPORTED) {
            LOG_E("IMF feature is not supported");
            PrintToConsole("Error: Operation is not supported. IMF is not supported on this device.");
            return EXIT_FAILURE;
        } else if (result == OHOS::testserver::TEST_SERVER_NO_ACTIVE_IME) {
            LOG_E("No active IME client");
            PrintToConsole("Error: No active input method keyboard.");
            return EXIT_FAILURE;
        } else {
            LOG_E("HideKeyboard failed with error: %{public}d", result);
            PrintToConsole("Error: Service is not available.");
            return EXIT_SERVICE_UNAVAILABLE;
        }
    }

    bool TestHelperCore::ValidateFontFileFormat(const std::string& filePath)
    {
        size_t dotPos = filePath.rfind('.');
        if (dotPos == std::string::npos) {
            PrintToConsole("Error: Invalid font file format. Only supports .ttf and .ttc files.");
            LOG_E("Font file has no extension: %{public}s", filePath.c_str());
            return false;
        }
        std::string extension = filePath.substr(dotPos);
        if (extension != ".ttf" && extension != ".ttc") {
            PrintToConsole("Error: Invalid font file format. Only supports .ttf and .ttc files.");
            LOG_E("Invalid font file extension: %{public}s", extension.c_str());
            return false;
        }
        return true;
    }

    int32_t TestHelperCore::HandleGetFontname(const std::string& fontPath)
    {
        LOG_I("HandleGetFontname called with path: %{public}s", fontPath.c_str());
        
        const std::string prefix = "/data/local/tmp/";
        if (fontPath.empty() || fontPath.find(prefix) != 0) {
            LOG_E("Invalid font path");
            PrintToConsole("Error: Invalid font path. Please provide a valid absolute path under the /data/local/tmp");
            return EXIT_FAILURE;
        }
        if (!ValidateFontFileFormat(fontPath)) {
            return EXIT_FAILURE;
        }
        std::string fileName = fontPath.substr(prefix.length());
        if (fileName.empty() || fileName.find("..") != std::string::npos) {
            LOG_E("Invalid font path: %{public}s", fontPath.c_str());
            PrintToConsole("Error: Invalid font path. Please provide a valid absolute path under the /data/local/tmp");
            return EXIT_FAILURE;
        }
        int fd = open(fontPath.c_str(), O_RDONLY);
        if (fd < 0) {
            LOG_E("Font file not found: %{public}s", fontPath.c_str());
            PrintToConsole("Error: Font file not found: " + fontPath);
            return EXIT_FAILURE;
        }
        fdsan_exchange_owner_tag(fd, 0, fdsan_create_owner_tag(FDSAN_OWNER_TYPE_FILE, LOG_DOMAIN));
        
#ifndef ARKXTEST_FONT_ENABLE
        LOG_E("Font management is not supported");
        PrintToConsole("Error: Operation is not supported. Font management is not supported on this device.");
        fdsan_close_with_tag(fd, fdsan_create_owner_tag(FDSAN_OWNER_TYPE_FILE, LOG_DOMAIN));
        return EXIT_NOT_SUPPORTED;
#else
        std::vector<std::string> fontNames;
        fontNames = Rosen::FontToolSet::GetInstance().GetFontFullName(fd);
        fdsan_close_with_tag(fd, fdsan_create_owner_tag(FDSAN_OWNER_TYPE_FILE, LOG_DOMAIN));

        if (fontNames.empty()) {
            LOG_E("No font name found");
            PrintToConsole("Error: Service is not available.");
            return EXIT_SERVICE_UNAVAILABLE;
        }
        std::string fontName = fontNames[0];
        PrintToConsole("Font name: " + fontName);
        LOG_I("HandleGetFontname completed successfully");
        return EXIT_SUCCESS;
#endif
    }

    int32_t TestHelperCore::HandleInstallFont(const std::string& fontPath)
    {
        LOG_I("HandleInstallFont called with path: %{public}s", fontPath.c_str());
        
        const std::string prefix = "/data/local/tmp/";
        if (fontPath.empty() || fontPath.find(prefix) != 0) {
            LOG_E("Invalid font path");
            PrintToConsole("Error: Invalid font path. Please provide a valid absolute path under the /data/local/tmp");
            return EXIT_FAILURE;
        }
        if (!ValidateFontFileFormat(fontPath)) {
            return EXIT_FAILURE;
        }
        std::string fileName = fontPath.substr(prefix.length());
        if (fileName.empty() || fileName.find("..") != std::string::npos) {
            LOG_E("Invalid font path: %{public}s", fontPath.c_str());
            PrintToConsole("Error: Invalid font path. Please provide a valid absolute path under the /data/local/tmp");
            return EXIT_FAILURE;
        }
        int fd = open(fontPath.c_str(), O_RDONLY);
        if (fd < 0) {
            LOG_E("Font file not found: %{public}s", fontPath.c_str());
            PrintToConsole("Error: Font file not found: " + fontPath);
            return EXIT_FAILURE;
        }
        fdsan_exchange_owner_tag(fd, 0, fdsan_create_owner_tag(FDSAN_OWNER_TYPE_FILE, LOG_DOMAIN));
        fdsan_close_with_tag(fd, fdsan_create_owner_tag(FDSAN_OWNER_TYPE_FILE, LOG_DOMAIN));
        
#ifndef ARKXTEST_FONT_ENABLE
        LOG_E("Font management is not supported");
        PrintToConsole("Error: Operation is not supported. Font management is not supported on this device.");
        return EXIT_NOT_SUPPORTED;
#else
        auto result = OHOS::testserver::TestServerClient::GetInstance().InstallFont(fontPath);
        if (result == OHOS::testserver::TEST_SERVER_OK) {
            PrintToConsole("Font installed successfully from " + fontPath);
            LOG_I("HandleInstallFont completed successfully");
            return EXIT_SUCCESS;
        } else if (result == OHOS::testserver::TEST_SERVER_FONT_ALREADY_INSTALLED) {
            LOG_E("Font is already installed");
            PrintToConsole("Error: Font is already installed.");
            return EXIT_FAILURE;
        } else {
            LOG_E("InstallFont failed with error: %{public}d", result);
            PrintToConsole("Error: Service is not available.");
            return EXIT_SERVICE_UNAVAILABLE;
        }
#endif
    }

    int32_t TestHelperCore::HandleUninstallFont(const std::string& fontName)
    {
        LOG_I("HandleUninstallFont called with name: %{public}s", fontName.c_str());

        if (fontName.empty()) {
            LOG_E("Font name is empty");
            PrintToConsole("Error: Font not found: ");
            return EXIT_FAILURE;
        }
#ifndef ARKXTEST_FONT_ENABLE
        LOG_E("Font management is not supported");
        PrintToConsole("Error: Operation is not supported. Font management is not supported on this device.");
        return EXIT_NOT_SUPPORTED;
#else
        auto result = OHOS::testserver::TestServerClient::GetInstance().UninstallFont(fontName);
        if (result == OHOS::testserver::TEST_SERVER_OK) {
            PrintToConsole("Font uninstalled successfully: " + fontName);
            LOG_I("HandleUninstallFont completed successfully");
            return EXIT_SUCCESS;
        } else if (result == OHOS::testserver::TEST_SERVER_FONT_NOT_FOUND) {
            LOG_E("Font not found: %{public}s", fontName.c_str());
            PrintToConsole("Error: Font not found: " + fontName);
            return EXIT_FAILURE;
        } else {
            LOG_E("UninstallFont failed with error: %{public}d", result);
            PrintToConsole("Error: Service is not available.");
            return EXIT_SERVICE_UNAVAILABLE;
        }
#endif
    }

    int32_t TestHelperCore::HandleSetViewMode(const std::string& mode)
    {
        LOG_I("HandleSetViewMode called with mode: %{public}s", mode.c_str());
        if (mode != "dark" && mode != "light") {
            LOG_E("Invalid mode: %{public}s", mode.c_str());
            PrintToConsole("Error: Invalid view mode. Mode must be 'dark' or 'light'.");
            return EXIT_FAILURE;
        }
        
        std::string currentMode = OHOS::testserver::TestServerClient::GetInstance().GetViewMode();
        if (currentMode == "NOT_SUPPORTED") {
            LOG_E("View mode is not supported");
            PrintToConsole("Error: Operation is not supported. View mode is not supported on this device.");
            return EXIT_FAILURE;
        }
        if (!currentMode.empty() && currentMode == mode) {
            LOG_I("View mode is already set to %{public}s", mode.c_str());
            PrintToConsole("Error: View mode is already set to " + mode + ".");
            return EXIT_FAILURE;
        }
        
        auto result = OHOS::testserver::TestServerClient::GetInstance().SetViewMode(mode);
        if (result == OHOS::testserver::TEST_SERVER_NOT_SUPPORTED) {
            LOG_E("View mode is not supported");
            PrintToConsole("Error: Operation is not supported. View mode is not supported on this device.");
            return EXIT_FAILURE;
        }
        if (result == OHOS::testserver::TEST_SERVER_OK) {
            PrintToConsole("Set view mode to " + mode + " successfully.");
            LOG_I("HandleSetViewMode completed successfully");
            return EXIT_SUCCESS;
        } else {
            LOG_E("SetViewMode failed with error: %{public}d", result);
            PrintToConsole("Error: Service is not available.");
            return EXIT_SERVICE_UNAVAILABLE;
        }
    }

    bool TestHelperCore::ValidateGPXFilePath(const std::string& filePath)
    {
        const std::string prefix = "/data/local/tmp/";
        if (filePath.empty() || filePath.find(prefix) != 0) {
            PrintToConsole("Error: Invalid path. Please provide a valid gpx file path under the /data/local/tmp");
            return false;
        }
        size_t dotPos = filePath.rfind('.');
        if (dotPos == std::string::npos) {
            PrintToConsole("Error: Invalid path. Please provide a valid gpx file path under the /data/local/tmp");
            return false;
        }
        std::string extension = filePath.substr(dotPos);
        if (extension != ".gpx") {
            PrintToConsole("Error: Invalid path. Please provide a valid gpx file path under the /data/local/tmp");
            return false;
        }
        std::string fileName = filePath.substr(prefix.length());
        if (fileName.empty() || fileName.find("..") != std::string::npos) {
            PrintToConsole("Error: Invalid path. Please provide a valid gpx file path under the /data/local/tmp");
            return false;
        }
        if (access(filePath.c_str(), F_OK) != 0) {
            PrintToConsole("Error: Invalid path. Please provide a valid gpx file path under the /data/local/tmp");
            return false;
        }
        return true;
    }

    bool TestHelperCore::ValidateTimeInterval(int32_t timeInterval)
    {
        if (timeInterval <= 0) {
            PrintToConsole("Error: The parameter validation has failed. timeInterval must be greater than 0.");
            LOG_E("Invalid time interval: %{public}d", timeInterval);
            return false;
        }
        if (timeInterval > MAX_TIME_INTERVAL) {
            PrintToConsole("Error: The parameter validation has failed. timeInterval must be less than 3600.");
            LOG_E("Time interval too large: %{public}d", timeInterval);
            return false;
        }
        return true;
    }

    int32_t TestHelperCore::HandleEnableLocationMock()
    {
        LOG_I("HandleEnableLocationMock called");
        auto& testServerClient = OHOS::testserver::TestServerClient::GetInstance();
        int32_t result = testServerClient.EnableLocationMock();
        if (result == OHOS::testserver::TEST_SERVER_OK) {
            PrintToConsole("Enable location mock successfully.");
            LOG_I("HandleEnableLocationMock completed successfully");
            return EXIT_SUCCESS;
        } else if (result == OHOS::testserver::TEST_SERVER_NOT_SUPPORTED) {
            LOG_E("EnableLocationMock not supported on this device");
            PrintToConsole("Error: Operation is not supported. Location mock is not supported on this device.");
            return EXIT_FAILURE;
        } else {
            LOG_E("EnableLocationMock failed with error: %{public}d", result);
            PrintToConsole("Error: Service is not available.");
            return EXIT_SERVICE_UNAVAILABLE;
        }
    }

    int32_t TestHelperCore::HandleDisableLocationMock()
    {
        LOG_I("HandleDisableLocationMock called");
        auto& testServerClient = OHOS::testserver::TestServerClient::GetInstance();
        int32_t result = testServerClient.DisableLocationMock();
        if (result == OHOS::testserver::TEST_SERVER_OK) {
            PrintToConsole("Disable location mock successfully.");
            LOG_I("HandleDisableLocationMock completed successfully");
            return EXIT_SUCCESS;
        } else if (result == OHOS::testserver::TEST_SERVER_NOT_SUPPORTED) {
            LOG_E("DisableLocationMock not supported on this device");
            PrintToConsole("Error: Operation is not supported. Location mock is not supported on this device.");
            return EXIT_FAILURE;
        } else {
            LOG_E("DisableLocationMock failed with error: %{public}d", result);
            PrintToConsole("Error: Service is not available.");
            return EXIT_SERVICE_UNAVAILABLE;
        }
    }

    int32_t TestHelperCore::HandleSetMockedLocations(const std::string& gpxFile, int32_t timeInterval)
    {
        xmlInitParser();
        if (!ValidateGPXFilePath(gpxFile)) {
            xmlCleanupParser();
            return EXIT_FAILURE;
        }
        if (!ValidateTimeInterval(timeInterval)) {
            xmlCleanupParser();
            return EXIT_FAILURE;
        }
        auto locations = GPXParser::ParseFile(gpxFile);
        if (locations.empty()) {
            LOG_E("No valid locations parsed from GPX file");
            xmlCleanupParser();
            return EXIT_FAILURE;
        }
        if (locations.size() > MAX_MOCK_LOCATIONS) {
            PrintToConsole(
                "Error: The parameter validation in gpx file has failed. locations size must be less than 1000.");
            LOG_E("Too many locations: %{public}zu", locations.size());
            xmlCleanupParser();
            return EXIT_FAILURE;
        }
        auto& testServerClient = OHOS::testserver::TestServerClient::GetInstance();
        int32_t result = testServerClient.SetMockedLocations(locations, timeInterval);
        xmlCleanupParser();
        if (result == OHOS::testserver::TEST_SERVER_OK) {
            PrintToConsole("Set mocked locations successfully.");
            LOG_I("HandleSetMockedLocations completed successfully, locations: %{public}zu", locations.size());
            return EXIT_SUCCESS;
        } else if (result == OHOS::testserver::TEST_SERVER_NOT_SUPPORTED) {
            LOG_E("SetMockedLocations not supported on this device");
            PrintToConsole("Error: Operation is not supported. Location mock is not supported on this device.");
            return EXIT_FAILURE;
        } else {
            LOG_E("SetMockedLocations failed with error: %{public}d", result);
            PrintToConsole("Error: Service is not available.");
            return EXIT_SERVICE_UNAVAILABLE;
        }
    }
}