/*
 *
 *    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 "OTAProviderDelegate.h"
#import <Matter/Matter.h>
#include <fstream>

constexpr uint8_t kUpdateTokenLen = 32;

@interface OTAProviderDelegate ()
@property NSString * mOTAFilePath;
@property NSFileHandle * mFileHandle;
@property NSNumber * mFileOffset;
@property NSNumber * mFileEndOffset;
@property DeviceSoftwareVersionModel * candidate;
@end

@implementation OTAProviderDelegate

- (instancetype)init
{
    if (self = [super init]) {
        _selectedCandidate = [[DeviceSoftwareVersionModel alloc] init];
        _action = MTROTASoftwareUpdateProviderOTAApplyUpdateActionProceed;
        _userConsentState = OTAProviderUserUnknown;
        _delayedActionTime = nil;
        _timedInvokeTimeoutMs = nil;
        _userConsentNeeded = nil;
        _queryImageStatus = MTROTASoftwareUpdateProviderOTAQueryStatusNotAvailable;
    }
    return self;
}

- (void)handleQueryImageForNodeID:(NSNumber * _Nonnull)nodeID
                       controller:(MTRDeviceController * _Nonnull)controller
                           params:(MTROTASoftwareUpdateProviderClusterQueryImageParams * _Nonnull)params
                       completion:(void (^_Nonnull)(MTROTASoftwareUpdateProviderClusterQueryImageResponseParams * _Nullable data,
                                      NSError * _Nullable error))completion
{
    auto isBDXProtocolSupported =
        [params.protocolsSupported containsObject:@(MTROTASoftwareUpdateProviderOTADownloadProtocolBDXSynchronous)];
    if (!isBDXProtocolSupported) {
        _selectedCandidate.status = @(MTROTASoftwareUpdateProviderOTAQueryStatusDownloadProtocolNotSupported);
        completion(_selectedCandidate, nil);
        return;
    }

    auto hasCandidate = [self SelectOTACandidate:params.vendorID rPID:params.productID rSV:params.softwareVersion];
    if (!hasCandidate) {
        NSLog(@"Unable to select OTA Image.");
        _selectedCandidate.status = @(MTROTASoftwareUpdateProviderOTAQueryStatusNotAvailable);
        completion(_selectedCandidate, nil);
        return;
    }

    if (_delayedActionTime) {
        _selectedCandidate.delayedActionTime = _delayedActionTime;
    }

    _selectedCandidate.updateToken = [self generateUpdateToken];
    NSLog(@"Query Image Status: %hhu", _queryImageStatus);
    _selectedCandidate.status = @(_queryImageStatus);

    if (params.requestorCanConsent.integerValue == 1 && _userConsentNeeded) {
        _selectedCandidate.userConsentNeeded = _userConsentNeeded;
        NSLog(@"User Consent Needed: %@", _selectedCandidate.userConsentNeeded);
    }
    completion(_selectedCandidate, nil);
}

- (void)handleApplyUpdateRequestForNodeID:(NSNumber * _Nonnull)nodeID
                               controller:(MTRDeviceController * _Nonnull)controller
                                   params:(MTROTASoftwareUpdateProviderClusterApplyUpdateRequestParams * _Nonnull)params
                               completion:
                                   (void (^_Nonnull)(MTROTASoftwareUpdateProviderClusterApplyUpdateResponseParams * _Nullable data,
                                       NSError * _Nullable error))completion
{
    MTROTASoftwareUpdateProviderClusterApplyUpdateResponseParams * applyUpdateResponseParams =
        [[MTROTASoftwareUpdateProviderClusterApplyUpdateResponseParams alloc] init];
    applyUpdateResponseParams.action = @(_action);
    if (_delayedActionTime) {
        applyUpdateResponseParams.delayedActionTime = _delayedActionTime;
    }
    if (_timedInvokeTimeoutMs) {
        applyUpdateResponseParams.timedInvokeTimeoutMs = _timedInvokeTimeoutMs;
    }

    completion(applyUpdateResponseParams, nil);
}

- (void)handleNotifyUpdateAppliedForNodeID:(NSNumber * _Nonnull)nodeID
                                controller:(MTRDeviceController * _Nonnull)controller
                                    params:(MTROTASoftwareUpdateProviderClusterNotifyUpdateAppliedParams * _Nonnull)params
                                completion:(MTRStatusCompletion _Nonnull)completion
{
    completion(nil);
}

- (void)handleBDXTransferSessionBeginForNodeID:(NSNumber * _Nonnull)nodeID
                                    controller:(MTRDeviceController * _Nonnull)controller
                                fileDesignator:(NSString * _Nonnull)fileDesignator
                                        offset:(NSNumber * _Nonnull)offset
                                    completion:(void (^)(NSError * error))completion
{
    NSLog(@"BDX TransferSession begin with %@ (offset: %@)", fileDesignator, offset);

    auto * handle = [NSFileHandle fileHandleForReadingAtPath:fileDesignator];
    if (handle == nil) {
        auto errorString = [NSString stringWithFormat:@"Error accessing file at at %@", fileDesignator];
        auto error = [[NSError alloc] initWithDomain:@"OTAProviderDomain"
                                                code:MTRErrorCodeGeneralError
                                            userInfo:@{ NSLocalizedDescriptionKey : NSLocalizedString(errorString, nil) }];
        completion(error);
        return;
    }

    NSError * seekError = nil;
    [handle seekToOffset:[offset unsignedLongValue] error:&seekError];
    if (seekError != nil) {
        auto errorString = [NSString stringWithFormat:@"Error seeking file (%@) to offset %@", fileDesignator, offset];
        auto error = [[NSError alloc] initWithDomain:@"OTAProviderDomain"
                                                code:MTRErrorCodeGeneralError
                                            userInfo:@{ NSLocalizedDescriptionKey : NSLocalizedString(errorString, nil) }];
        completion(error);
        return;
    }

    uint64_t endOffset;
    if (![handle seekToEndReturningOffset:&endOffset error:&seekError]) {
        auto errorString = [NSString stringWithFormat:@"Error seeking file (%@) to end offset", fileDesignator];
        auto error = [[NSError alloc] initWithDomain:@"OTAProviderDomain"
                                                code:MTRErrorCodeGeneralError
                                            userInfo:@{ NSLocalizedDescriptionKey : NSLocalizedString(errorString, nil) }];
        completion(error);
        return;
    }

    _mFileHandle = handle;
    _mFileOffset = offset;
    _mFileEndOffset = @(endOffset);
    completion(nil);
}

- (void)handleBDXTransferSessionEndForNodeID:(NSNumber * _Nonnull)nodeID
                                  controller:(MTRDeviceController * _Nonnull)controller
                                       error:(NSError * _Nullable)error
{
    NSLog(@"BDX TransferSession end with error: %@", error);
    _mFileHandle = nil;
    _mFileOffset = nil;
    _mFileEndOffset = nil;
}

- (void)handleBDXQueryForNodeID:(NSNumber * _Nonnull)nodeID
                     controller:(MTRDeviceController * _Nonnull)controller
                      blockSize:(NSNumber * _Nonnull)blockSize
                     blockIndex:(NSNumber * _Nonnull)blockIndex
                    bytesToSkip:(NSNumber * _Nonnull)bytesToSkip
                     completion:(void (^)(NSData * _Nullable data, BOOL isEOF))completion
{
    NSLog(@"BDX Query received blockSize: %@, blockIndex: %@", blockSize, blockIndex);

    NSError * error = nil;
    auto offset = [_mFileOffset unsignedLongValue] + [bytesToSkip unsignedLongLongValue]
        + ([blockSize unsignedLongValue] * [blockIndex unsignedLongValue]);
    [_mFileHandle seekToOffset:offset error:&error];
    if (error != nil) {
        NSLog(@"Error seeking to offset %@", @(offset));
        completion(nil, NO);
        return;
    }

    NSData * data = [_mFileHandle readDataUpToLength:[blockSize unsignedLongValue] error:&error];
    if (error != nil) {
        NSLog(@"Error reading file %@", _mFileHandle);
        completion(nil, NO);
        return;
    }

    BOOL isEOF = offset + [blockSize unsignedLongValue] >= [_mFileEndOffset unsignedLongLongValue];
    completion(data, isEOF);
}

- (void)SetOTAFilePath:(const char *)path
{
    _mOTAFilePath = [NSString stringWithUTF8String:path];
}

- (NSData *)generateUpdateToken
{
    NSMutableData * updateTokenData = [NSMutableData dataWithCapacity:kUpdateTokenLen];
    for (unsigned int i = 0; i < kUpdateTokenLen / 4; ++i) {
        u_int32_t randomBits = arc4random();
        [updateTokenData appendBytes:(void *) &randomBits length:4];
    }

    return [NSData dataWithData:updateTokenData];
}

- (bool)SelectOTACandidate:(NSNumber *)requestorVendorID
                      rPID:(NSNumber *)requestorProductID
                       rSV:(NSNumber *)requestorSoftwareVersion
{
    auto vendorId = [requestorVendorID unsignedIntValue];
    auto productId = [requestorProductID unsignedIntValue];
    auto softwareVersion = [requestorSoftwareVersion unsignedLongValue];

    bool candidateFound = false;
    NSArray * sortedArray = [_candidates sortedArrayUsingSelector:@selector(CompareSoftwareVersions:)];
    for (DeviceSoftwareVersionModel * candidate : sortedArray) {
        auto candidateSoftwareVersionValid = candidate.deviceModelData.softwareVersionValid;
        auto candidateSoftwareVersion = [candidate.softwareVersion unsignedLongValue];
        auto candidateMinApplicableSoftwareVersion = [candidate.deviceModelData.minApplicableSoftwareVersion unsignedLongValue];
        auto candidateMaxApplicableSoftwareVersion = [candidate.deviceModelData.maxApplicableSoftwareVersion unsignedLongValue];
        auto candidateVendorId = [candidate.deviceModelData.vendorID unsignedIntValue];
        auto candidateProductId = [candidate.deviceModelData.productID unsignedIntValue];

        if (candidateSoftwareVersionValid && (softwareVersion < candidateSoftwareVersion)
            && (softwareVersion >= candidateMinApplicableSoftwareVersion)
            && (softwareVersion <= candidateMaxApplicableSoftwareVersion) && (vendorId == candidateVendorId)
            && (productId == candidateProductId)) {
            _selectedCandidate = candidate;
            _selectedCandidate.imageURI = candidate.deviceModelData.otaURL;
            candidateFound = true;
        }
    }

    return candidateFound;
}

@end

@implementation DeviceSoftwareVersionModelData
- (instancetype)init
{
    if (self = [super init]) {
        _cDVersionNumber = nil;

        _minApplicableSoftwareVersion = nil;

        _maxApplicableSoftwareVersion = nil;

        _otaURL = nil;
    }
    return self;
}

@end

@implementation DeviceSoftwareVersionModel
- (instancetype)init
{
    if (self = [super init]) {
        _deviceModelData = [[DeviceSoftwareVersionModelData alloc] init];
    }
    return self;
}
- (NSComparisonResult)CompareSoftwareVersions:(DeviceSoftwareVersionModel * _Nullable)otherObject
{
    return [self.deviceModelData.softwareVersion compare:otherObject.deviceModelData.softwareVersion];
}
@end
