/*
 *
 *    Copyright (c) 2022 Project CHIP Authors
 *
 *    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 "OTASoftwareUpdateInteractive.h"

#include <fstream>
#include <json/json.h>

constexpr size_t kOtaHeaderMaxSize = 1024;

MTROTAHeader * ParseOTAHeader(const char * otaFilePath)
{
    uint8_t otaFileContent[kOtaHeaderMaxSize];
    chip::ByteSpan buffer(otaFileContent);

    std::ifstream otaFile(otaFilePath, std::ifstream::in);
    if (!otaFile.is_open() || !otaFile.good()) {
        ChipLogError(SoftwareUpdate, "Error opening OTA image file: %s", otaFilePath);
        return nil;
    }

    otaFile.read(reinterpret_cast<char *>(otaFileContent), kOtaHeaderMaxSize);
    if (otaFile.bad()) {
        ChipLogError(SoftwareUpdate, "Error reading OTA image file: %s", otaFilePath);
        return nil;
    }

    NSError * error;
    return [MTROTAHeader headerFromData:[NSData dataWithBytes:buffer.data() length:buffer.size()] error:&error];
}

// Parses the JSON filepath and extracts DeviceSoftwareVersionModel parameters
static bool ParseJsonFileAndPopulateCandidates(
    const char * filepath, NSMutableArray<DeviceSoftwareVersionModel *> ** _Nonnull candidates)
{
    Json::Value root;
    Json::CharReaderBuilder builder;
    JSONCPP_STRING errs;
    std::ifstream ifs;

    builder["collectComments"] = true; // allow C/C++ type comments in JSON file
    ifs.open(filepath);

    if (!ifs.good()) {
        ChipLogError(SoftwareUpdate, "Error opening ifstream with file: \"%s\"", filepath);
        return false;
    }

    if (!parseFromStream(builder, ifs, &root, &errs)) {
        ChipLogError(SoftwareUpdate, "Error parsing JSON from file: \"%s\"", filepath);
        return false;
    }

    const Json::Value devSofVerModValue = root["deviceSoftwareVersionModel"];
    if (!devSofVerModValue || !devSofVerModValue.isArray()) {
        ChipLogError(SoftwareUpdate, "Error: Key deviceSoftwareVersionModel not found or its value is not of type Array");
        return false;
    }

    *candidates = [[NSMutableArray alloc] init];

    bool ret = false;
    for (auto iter : devSofVerModValue) {
        DeviceSoftwareVersionModel * candidate = [[DeviceSoftwareVersionModel alloc] init];

        auto vendorId = [NSNumber numberWithUnsignedInt:iter.get("vendorId", 1).asUInt()];
        auto productId = [NSNumber numberWithUnsignedInt:iter.get("productId", 1).asUInt()];
        auto softwareVersion = [NSNumber numberWithUnsignedLongLong:iter.get("softwareVersion", 10).asUInt64()];
        auto softwareVersionString = [NSString stringWithUTF8String:iter.get("softwareVersionString", "1.0.0").asCString()];
        auto cDVersionNumber = [NSNumber numberWithUnsignedInt:iter.get("cDVersionNumber", 0).asUInt()];
        auto softwareVersionValid = iter.get("softwareVersionValid", true).asBool() ? YES : NO;
        auto minApplicableSoftwareVersion =
            [NSNumber numberWithUnsignedLongLong:iter.get("minApplicableSoftwareVersion", 0).asUInt64()];
        auto maxApplicableSoftwareVersion =
            [NSNumber numberWithUnsignedLongLong:iter.get("maxApplicableSoftwareVersion", 1000).asUInt64()];
        auto otaURL = [NSString stringWithUTF8String:iter.get("otaURL", "https://test.com").asCString()];

        candidate.deviceModelData.vendorId = vendorId;
        candidate.deviceModelData.productId = productId;
        candidate.softwareVersion = softwareVersion;
        candidate.softwareVersionString = softwareVersionString;
        candidate.deviceModelData.cDVersionNumber = cDVersionNumber;
        candidate.deviceModelData.softwareVersionValid = softwareVersionValid;
        candidate.deviceModelData.minApplicableSoftwareVersion = minApplicableSoftwareVersion;
        candidate.deviceModelData.maxApplicableSoftwareVersion = maxApplicableSoftwareVersion;
        candidate.deviceModelData.otaURL = otaURL;
        [*candidates addObject:candidate];
        ret = true;
    }

    return ret;
}

CHIP_ERROR OTASoftwareUpdateSetFilePath::RunCommand()
{
    auto error = SetCandidatesFromFilePath(mOTACandidatesFilePath);
    SetCommandExitStatus(nil);
    return error;
}

CHIP_ERROR OTASoftwareUpdateSetParams::RunCommand()
{
    auto error = SetParams(mAction, mStatus, mUserConsentStatus, mUserConsentNeeded, mDelayedActionTime, mTimedInvokeTimeoutMs);
    SetCommandExitStatus(nil);
    return error;
}

CHIP_ERROR OTASoftwareUpdateSetParams::SetParams(chip::Optional<uint16_t> action, chip::Optional<uint16_t> status,
    chip::Optional<uint16_t> consent, chip::Optional<uint16_t> userConsentNeeded, chip::Optional<uint64_t> delayedActionTime,
    chip::Optional<uint64_t> timedInvokeTimeoutMs)
{
    CHIP_ERROR error = CHIP_NO_ERROR;
    if (action.HasValue()) {
        error = SetActionReplyStatus(action.Value());
        if (error != CHIP_NO_ERROR) {
            return error;
        }
    }
    if (delayedActionTime.HasValue()) {
        mOTADelegate.delayedActionTime = @(delayedActionTime.Value());
    }
    if (timedInvokeTimeoutMs.HasValue()) {
        mOTADelegate.timedInvokeTimeoutMs = @(timedInvokeTimeoutMs.Value());
    }
    if (status.HasValue()) {
        error = SetReplyStatus(status.Value());
        if (error != CHIP_NO_ERROR) {
            return error;
        }
    }
    if (consent.HasValue()) {
        error = SetUserConsentStatus(consent.Value());
        if (error != CHIP_NO_ERROR) {
            return error;
        }
    }
    if (userConsentNeeded.HasValue()) {
        error = SetUserConsentNeeded(userConsentNeeded.Value());
        if (error != CHIP_NO_ERROR) {
            return error;
        }
    }

    return error;
}

CHIP_ERROR OTASoftwareUpdateBase::SetActionReplyStatus(uint16_t action)
{
    CHIP_ERROR error = CHIP_NO_ERROR;
    if (action == 0) {
        mOTADelegate.action = MTROTASoftwareUpdateProviderOTAApplyUpdateActionProceed;
        ChipLogDetail(chipTool, "Successfully set action to: MTROTASoftwareUpdateProviderOTAApplyUpdateActionProceed");
    } else if (action == 1) {
        mOTADelegate.action = MTROTASoftwareUpdateProviderOTAApplyUpdateActionAwaitNextAction;
        ChipLogDetail(chipTool, "Successfully set action to: MTROTASoftwareUpdateProviderOTAApplyUpdateActionAwaitNextAction");
    } else if (action == 2) {
        mOTADelegate.action = MTROTASoftwareUpdateProviderOTAApplyUpdateActionDiscontinue;
        ChipLogDetail(chipTool, "Successfully set action to: MTROTASoftwareUpdateProviderOTAApplyUpdateActionDiscontinue");
    } else {
        ChipLogError(chipTool, "Only accepts the following: 0 (Proceed), 1 (Await Next Action), 2 (Discontinue)");
        error = CHIP_ERROR_INTERNAL;
    }
    return error;
}
CHIP_ERROR OTASoftwareUpdateBase::SetReplyStatus(uint16_t status)
{
    CHIP_ERROR error = CHIP_NO_ERROR;
    if (status == 0) {
        mOTADelegate.queryImageStatus = MTROTASoftwareUpdateProviderOTAQueryStatusUpdateAvailable;
        ChipLogDetail(chipTool, "Successfully set status to: MTROTASoftwareUpdateProviderOTAQueryStatusUpdateAvailable");
    } else if (status == 1) {
        mOTADelegate.queryImageStatus = MTROTASoftwareUpdateProviderOTAQueryStatusBusy;
        ChipLogDetail(chipTool, "Successfully set status to: MTROTASoftwareUpdateProviderOTAQueryStatusBusy");
    } else if (status == 2) {
        mOTADelegate.queryImageStatus = MTROTASoftwareUpdateProviderOTAQueryStatusNotAvailable;
        ChipLogDetail(chipTool, "Successfully set status to: MTROTASoftwareUpdateProviderOTAQueryStatusNotAvailable");
    } else if (status == 4) {
        mOTADelegate.queryImageStatus = MTROTASoftwareUpdateProviderOTAQueryStatusDownloadProtocolNotSupported;
        ChipLogDetail(
            chipTool, "Successfully set status to: MTROTASoftwareUpdateProviderOTAQueryStatusDownloadProtocolNotSupported");
    } else {
        ChipLogError(chipTool, "Only accepts the following: 0 (Available), 1 (Busy), 2 (Not Available), 3 (Not Supported)");
        error = CHIP_ERROR_INTERNAL;
    }
    return error;
}

CHIP_ERROR OTASoftwareUpdateBase::SetUserConsentStatus(uint16_t consent)
{
    CHIP_ERROR error = CHIP_NO_ERROR;
    if (consent == 0) {
        mOTADelegate.userConsentState = OTAProviderUserGranted;
        ChipLogDetail(chipTool, "Successfully set User Consent to: OTAProviderUserGranted");
    } else if (consent == 1) {
        mOTADelegate.userConsentState = OTAProviderUserObtaining;
        ChipLogDetail(chipTool, "Successfully set User Consent to: OTAProviderUserObtaining");
    } else if (consent == 2) {
        mOTADelegate.userConsentState = OTAProviderUserDenied;
        ChipLogDetail(chipTool, "Successfully set User Consent to: OTAProviderUserDenied");
    } else {
        ChipLogError(chipTool, "Only accepts the following: 0 (granted), 1 (obtaining), and 2 (denied).");
        error = CHIP_ERROR_INTERNAL;
    }
    return error;
}

CHIP_ERROR OTASoftwareUpdateBase::SetUserConsentNeeded(uint16_t userConsentNeeded)
{
    CHIP_ERROR error = CHIP_NO_ERROR;
    if (userConsentNeeded == 0) {
        mOTADelegate.userConsentNeeded = @(0);
        ChipLogDetail(chipTool, "Successfully set User Consent to: OTAProviderUserGranted");
    } else if (userConsentNeeded == 1) {
        mOTADelegate.userConsentNeeded = @(1);
        ChipLogDetail(chipTool, "Successfully set User Consent to: OTAProviderUserObtaining");
    } else {
        ChipLogError(chipTool, "Only accepts the following: 0 (Not Needed), and 1 (Needed).");
        error = CHIP_ERROR_INTERNAL;
    }
    return error;
}

CHIP_ERROR OTASoftwareUpdateBase::SetCandidatesFromFilePath(char * _Nonnull filePath)
{
    NSMutableArray<DeviceSoftwareVersionModel *> * candidates;
    ChipLogDetail(chipTool, "Setting candidates from file path: %s", filePath);
    VerifyOrReturnError(ParseJsonFileAndPopulateCandidates(filePath, &candidates), CHIP_ERROR_INTERNAL);

    for (DeviceSoftwareVersionModel * candidate : candidates) {
        auto otaURL = [candidate.deviceModelData.otaURL UTF8String];
        auto header = ParseOTAHeader(otaURL);
        VerifyOrReturnError(header != nil, CHIP_ERROR_INVALID_ARGUMENT);

        ChipLogDetail(chipTool, "Validating image list candidate %s: ", [candidate.deviceModelData.otaURL UTF8String]);

        auto vendorId = [candidate.deviceModelData.vendorId unsignedIntValue];
        auto productId = [candidate.deviceModelData.productId unsignedIntValue];
        auto softwareVersion = [candidate.softwareVersion unsignedLongValue];
        auto softwareVersionString = [candidate.softwareVersionString UTF8String];
        auto softwareVersionStringLength = [candidate.softwareVersionString length];
        auto minApplicableSoftwareVersion = [candidate.deviceModelData.minApplicableSoftwareVersion unsignedLongValue];
        auto maxApplicableSoftwareVersion = [candidate.deviceModelData.maxApplicableSoftwareVersion unsignedLongValue];

        auto headerVendorId = [header.vendorID unsignedIntValue];
        auto headerProductId = [header.productID unsignedIntValue];
        auto headerSoftwareVersion = [header.softwareVersion unsignedLongValue];
        auto headerSoftwareVersionString = [header.softwareVersionString UTF8String];
        auto headerSoftwareVersionStringLength = [header.softwareVersionString length];

        VerifyOrReturnError(vendorId == headerVendorId, CHIP_ERROR_INVALID_ARGUMENT);
        VerifyOrReturnError(productId == headerProductId, CHIP_ERROR_INVALID_ARGUMENT);
        VerifyOrReturnError(softwareVersion == headerSoftwareVersion, CHIP_ERROR_INVALID_ARGUMENT);
        VerifyOrReturnError(softwareVersionStringLength == headerSoftwareVersionStringLength, CHIP_ERROR_INVALID_ARGUMENT);
        VerifyOrReturnError(memcmp(softwareVersionString, headerSoftwareVersionString, headerSoftwareVersionStringLength) == 0,
            CHIP_ERROR_INVALID_ARGUMENT);

        if (header.minApplicableVersion) {
            auto version = [header.minApplicableVersion unsignedLongValue];
            VerifyOrReturnError(minApplicableSoftwareVersion == version, CHIP_ERROR_INVALID_ARGUMENT);
        }

        if (header.maxApplicableVersion) {
            auto version = [header.maxApplicableVersion unsignedLongValue];
            VerifyOrReturnError(maxApplicableSoftwareVersion == version, CHIP_ERROR_INVALID_ARGUMENT);
        }
    }

    mOTADelegate.candidates = candidates;
    return CHIP_NO_ERROR;
}

CHIP_ERROR OTASoftwareUpdateBase::Run()
{
    if (!IsInteractive()) {
        ChipLogError(chipTool, "OTA software update commands can only be ran in interactive mode.");
        return CHIP_ERROR_INTERNAL;
    }
    return CHIPCommandBridge::Run();
}
