/**
 *
 *    Copyright (c) 2021 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.
 */

#import "MTRThreadOperationalDataset.h"

#include "MTRLogging.h"
#include <lib/support/Span.h>
#include <lib/support/ThreadOperationalDataset.h>

size_t const MTRSizeThreadNetworkName = chip::Thread::kSizeNetworkName;
size_t const MTRSizeThreadExtendedPANID = chip::Thread::kSizeExtendedPanId;
size_t const MTRSizeThreadMasterKey = chip::Thread::kSizeMasterKey;
size_t const MTRSizeThreadPSKc = chip::Thread::kSizePSKc;
size_t const MTRSizeThreadPANID = 2; // Thread's PAN ID is 2 bytes

@interface MTRThreadOperationalDataset ()

@property (readonly) chip::Thread::OperationalDataset cppThreadOperationalDataset;

@end

@implementation MTRThreadOperationalDataset

- (instancetype _Nullable)initWithNetworkName:(NSString *)networkName
                                extendedPANID:(NSData *)extendedPANID
                                    masterKey:(NSData *)masterKey
                                         PSKc:(NSData *)PSKc
                                      channel:(NSNumber *)channel
                                        panID:(NSData *)panID
{
    if (self = [super init]) {
        _networkName = networkName;
        _extendedPANID = extendedPANID;
        _masterKey = masterKey;
        _PSKc = PSKc;
        _channel = channel;
        _panID = panID;
        _cppThreadOperationalDataset = chip::Thread::OperationalDataset();
        if ([self _populateCppOperationalDataset]) {
            return self;
        }
    }
    return nil;
}

- (BOOL)_populateCppOperationalDataset
{
    _cppThreadOperationalDataset.Clear();
    _cppThreadOperationalDataset.SetNetworkName([self.networkName cStringUsingEncoding:NSUTF8StringEncoding]);

    if (![self _checkDataLength:self.extendedPANID expectedLength:MTRSizeThreadExtendedPANID]) {
        MTR_LOG_ERROR("Invalid ExtendedPANID");
        return NO;
    }
    uint8_t extendedPanId[MTRSizeThreadExtendedPANID];
    [self.extendedPANID getBytes:&extendedPanId length:MTRSizeThreadExtendedPANID];
    _cppThreadOperationalDataset.SetExtendedPanId(extendedPanId);

    if (![self _checkDataLength:self.masterKey expectedLength:MTRSizeThreadMasterKey]) {
        MTR_LOG_ERROR("Invalid MasterKey");
        return NO;
    }
    uint8_t masterKey[MTRSizeThreadMasterKey];
    [self.masterKey getBytes:&masterKey length:MTRSizeThreadMasterKey];
    _cppThreadOperationalDataset.SetMasterKey(masterKey);

    if (![self _checkDataLength:self.PSKc expectedLength:MTRSizeThreadPSKc]) {
        MTR_LOG_ERROR("Invalid PKSc");
        return NO;
    }
    uint8_t PSKc[MTRSizeThreadPSKc];
    [self.PSKc getBytes:&PSKc length:MTRSizeThreadPSKc];
    _cppThreadOperationalDataset.SetPSKc(PSKc);

    _cppThreadOperationalDataset.SetChannel([self.channel unsignedShortValue]);

    // Thread's PAN ID is 2 bytes
    if (![self _checkDataLength:self.panID expectedLength:MTRSizeThreadPANID]) {
        MTR_LOG_ERROR("Invalid PAN ID");
        return NO;
    }
    uint16_t panID;
    memcpy(&panID, [self.panID bytes], MTRSizeThreadPANID);
    // The underlying CPP class assumes Big Endianness for the panID
    _cppThreadOperationalDataset.SetPanId(CFSwapInt16HostToBig(panID));

    return YES;
}

- (BOOL)_checkDataLength:(NSData *)data expectedLength:(size_t)expectedLength
{
    if (data.length != expectedLength) {
        MTR_LOG_ERROR("Length Check Failed. Length:%tu is incorrect, must be %tu", data.length, expectedLength);
        return NO;
    }
    return YES;
}

- (instancetype _Nullable)initWithData:(NSData *)data
{
    chip::ByteSpan span = chip::ByteSpan((uint8_t *) data.bytes, data.length);
    auto dataset = chip::Thread::OperationalDataset();
    CHIP_ERROR error = dataset.Init(span);
    if (error != CHIP_NO_ERROR) {
        MTR_LOG_ERROR("Failed to parse data, cannot construct Operational Dataset. %s", chip::ErrorStr(error));
        return nil;
    }
    // len+1 for null termination
    char networkName[MTRSizeThreadNetworkName + 1];
    uint8_t pskc[MTRSizeThreadPSKc];
    uint8_t extendedPANID[MTRSizeThreadExtendedPANID];
    uint8_t masterKey[MTRSizeThreadMasterKey];
    uint16_t panID;
    uint16_t channel;
    dataset.GetNetworkName(networkName);
    dataset.GetExtendedPanId(extendedPANID);
    dataset.GetMasterKey(masterKey);
    dataset.GetPSKc(pskc);
    dataset.GetPanId(panID);
    dataset.GetChannel(channel);
    panID = CFSwapInt16BigToHost(panID);

    return [self initWithNetworkName:[NSString stringWithUTF8String:networkName]
                       extendedPANID:[NSData dataWithBytes:extendedPANID length:MTRSizeThreadExtendedPANID]
                           masterKey:[NSData dataWithBytes:masterKey length:MTRSizeThreadMasterKey]
                                PSKc:[NSData dataWithBytes:pskc length:MTRSizeThreadPSKc]
                             channel:@(channel)
                               panID:[NSData dataWithBytes:&panID length:sizeof(uint16_t)]];
}

- (NSData *)data
{
    chip::ByteSpan span = _cppThreadOperationalDataset.AsByteSpan();
    return [NSData dataWithBytes:span.data() length:span.size()];
}

@end
