/*
 *   Copyright (c) 2022 Project CHIP Authors
 *   All rights reserved.
 *
 *   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.
 *
 */

#pragma once

#include "../common/CHIPCommandBridge.h"
#include <app/tests/suites/commands/log/LogCommands.h>
#include <app/tests/suites/commands/system/SystemCommands.h>
#include <app/tests/suites/include/ConstraintsChecker.h>
#include <app/tests/suites/include/PICSChecker.h>
#include <app/tests/suites/include/ValueChecker.h>
#include <lib/support/UnitTestUtils.h>
#include <map>
#include <string>

#import <Matter/Matter.h>

#import "MTRDevice_Externs.h"
#import "MTRError_Utils.h"

class TestCommandBridge;

NS_ASSUME_NONNULL_BEGIN
namespace {
const char basePath[] = "./src/app/tests/suites/commands/delay/scripts/";
const char * getScriptsFolder() { return basePath; }
} // namespace

constexpr const char * kDefaultKey = "default";

@interface TestDeviceControllerDelegate : NSObject <MTRDeviceControllerDelegate>
@property TestCommandBridge * commandBridge;
@property chip::NodeId deviceId;
@property BOOL active; // Whether to pass on notifications to the commandBridge

- (void)controller:(MTRDeviceController *)controller statusUpdate:(MTRCommissioningStatus)status;
- (void)controller:(MTRDeviceController *)controller commissioningSessionEstablishmentDone:(NSError * _Nullable)error;
- (void)controller:(MTRDeviceController *)controller commissioningComplete:(NSError * _Nullable)error;

- (instancetype)init NS_UNAVAILABLE;
- (instancetype)initWithTestCommandBridge:(TestCommandBridge *)commandBridge;
@end

NS_ASSUME_NONNULL_END

constexpr uint16_t kTimeoutInSeconds = 90;

class TestCommandBridge : public CHIPCommandBridge,
                          public ValueChecker,
                          public ConstraintsChecker,
                          public PICSChecker,
                          public LogCommands,
                          public SystemCommands {
public:
    TestCommandBridge(const char * _Nonnull commandName)
        : CHIPCommandBridge(commandName)
        , mDeviceControllerDelegate([[TestDeviceControllerDelegate alloc] initWithTestCommandBridge:this])
    {
        AddArgument("delayInMs", 0, UINT64_MAX, &mDelayInMs);
        AddArgument("PICS", &mPICSFilePath);
    }

    ~TestCommandBridge() {};

    /////////// CHIPCommand Interface /////////
    CHIP_ERROR RunCommand() override
    {
        if (mPICSFilePath.HasValue()) {
            PICS.SetValue(PICSBooleanReader::Read(mPICSFilePath.Value()));
        }

        mCallbackQueue = dispatch_queue_create("com.chip-tool.command", DISPATCH_QUEUE_SERIAL);

        NextTest();
        return CHIP_NO_ERROR;
    }

    chip::System::Clock::Timeout GetWaitDuration() const override { return chip::System::Clock::Seconds16(kTimeoutInSeconds); }

    virtual void NextTest() = 0;

    // Support for tests that asynchronously come up with a status of some
    // sort.  Subclasses are expected to compare the provided status to the
    // expected status for the test.
    virtual void OnStatusUpdate(const chip::app::StatusIB & status) = 0;

    void Exit(std::string message, CHIP_ERROR err = CHIP_ERROR_INTERNAL) override
    {
        ChipLogError(chipTool, " ***** Test Failure: %s\n", message.c_str());
        SetCommandExitStatus(err);
    }

    /////////// DelayCommands /////////
    // This function is a modified version of the one in DelayCommands.cpp and is needed here in order to
    // skip compilation of DelayCommands, which needs to link against SDK internals.
    CHIP_ERROR WaitForMs(
        const char * _Nullable identity, const chip::app::Clusters::DelayCommands::Commands::WaitForMs::Type & value)
    {
        dispatch_time_t delayTime = dispatch_time(DISPATCH_TIME_NOW, (int64_t)(value.ms * NSEC_PER_MSEC));
        dispatch_after(delayTime, mCallbackQueue, ^(void) {
            NextTest();
        });
        return CHIP_NO_ERROR;
    }

    // This function is identical to DelayCommands.cpp and is needed here in order to
    // skip compilation of DelayCommands, which needs to link against SDK internals.
    CHIP_ERROR WaitForMessage(
        const char * _Nullable identity, const chip::app::Clusters::DelayCommands::Commands::WaitForMessage::Type & value)
    {
        VerifyOrReturnError(!value.message.empty(), CHIP_ERROR_INVALID_ARGUMENT);

        const char * scriptDir = getScriptsFolder();
        constexpr const char * scriptName = "WaitForMessage.py";
        const char * registerKeyValue = value.registerKey.HasValue() ? value.registerKey.Value().data() : kDefaultKey;
        const size_t registerKeyLen = value.registerKey.HasValue() ? value.registerKey.Value().size() : strlen(kDefaultKey);

        char command[128];
        VerifyOrReturnError(
            snprintf(command, sizeof(command), "%s%s %.*s %.*s", scriptDir, scriptName, static_cast<int>(registerKeyLen),
                registerKeyValue, static_cast<int>(value.message.size()), value.message.data())
                >= 0,
            CHIP_ERROR_INTERNAL);
        return RunInternal(command);
    }

    // This function is identical to DelayCommands.cpp and is needed here in order to
    // skip compilation of DelayCommands, which needs to link against SDK internals.
    CHIP_ERROR RunInternal(const char * _Nonnull command)
    {
        VerifyOrReturnError(system(command) == 0, CHIP_ERROR_INTERNAL);
        return ContinueOnChipMainThread(CHIP_NO_ERROR);
    }

    CHIP_ERROR WaitForCommissionee(
        const char * _Nullable identity, const chip::app::Clusters::DelayCommands::Commands::WaitForCommissionee::Type & value)
    {
        MTRDeviceController * controller = GetCommissioner(identity);
        VerifyOrReturnError(controller != nil, CHIP_ERROR_INCORRECT_STATE);

        SetIdentity(identity);

        // Invalidate our existing CASE session; otherwise trying to work with
        // our device will just reuse it without establishing a new CASE
        // session when a reboot is done on the server, and then our next
        // interaction will time out.
        if (value.expireExistingSession.ValueOr(true)) {
            if (GetDevice(identity) != nil) {
                [GetDevice(identity) invalidateCASESession];
                mConnectedDevices[identity] = nil;
            }
        }

        mConnectedDevices[identity] = [MTRBaseDevice deviceWithNodeID:@(value.nodeId) controller:controller];
        dispatch_async(mCallbackQueue, ^{
            NextTest();
        });
        return CHIP_NO_ERROR;
    }

    /////////// CommissionerCommands-like Interface /////////
    CHIP_ERROR PairWithCode(
        const char * _Nullable identity, const chip::app::Clusters::CommissionerCommands::Commands::PairWithCode::Type & value)
    {
        MTRDeviceController * controller = GetCommissioner(identity);
        VerifyOrReturnError(controller != nil, CHIP_ERROR_INCORRECT_STATE);

        SetIdentity(identity);
        [controller setDeviceControllerDelegate:mDeviceControllerDelegate queue:mCallbackQueue];
        [mDeviceControllerDelegate setDeviceId:value.nodeId];
        [mDeviceControllerDelegate setActive:YES];

        NSString * payloadStr = [[NSString alloc] initWithBytes:value.payload.data()
                                                         length:value.payload.size()
                                                       encoding:NSUTF8StringEncoding];
        NSError * err;
        auto * payload = [MTRSetupPayload setupPayloadWithOnboardingPayload:payloadStr error:&err];
        if (err != nil) {
            return MTRErrorToCHIPErrorCode(err);
        }
        BOOL ok = [controller setupCommissioningSessionWithPayload:payload newNodeID:@(value.nodeId) error:&err];
        if (ok == YES) {
            return CHIP_NO_ERROR;
        }

        return MTRErrorToCHIPErrorCode(err);
    }

    CHIP_ERROR GetCommissionerNodeId(const char * _Nullable identity,
        const chip::app::Clusters::CommissionerCommands::Commands::GetCommissionerNodeId::Type & value,
        void (^_Nonnull OnResponse)(const chip::GetCommissionerNodeIdResponse &))
    {
        auto * controller = GetCommissioner(identity);
        VerifyOrReturnError(controller != nil, CHIP_ERROR_INCORRECT_STATE);

        auto id = [controller.controllerNodeId unsignedLongLongValue];
        ChipLogProgress(chipTool, "Commissioner Node Id: %llu", id);

        chip::GetCommissionerNodeIdResponse outValue;
        outValue.nodeId = id;

        dispatch_async(mCallbackQueue, ^{
            OnResponse(outValue);
        });

        return CHIP_NO_ERROR;
    }

    /////////// SystemCommands Interface /////////
    CHIP_ERROR ContinueOnChipMainThread(CHIP_ERROR err) override
    {
        if (CHIP_NO_ERROR == err) {
            dispatch_async(mCallbackQueue, ^{
                NextTest();
            });
        } else {
            Exit(chip::ErrorStr(err), err);
        }
        return CHIP_NO_ERROR;
    }

    MTRBaseDevice * _Nullable GetDevice(const char * _Nullable identity)
    {
        SetIdentity(identity);
        return mConnectedDevices[identity];
    }

    // PairingDeleted and PairingComplete need to be public so our pairing
    // delegate can call them.
    void PairingDeleted()
    {
        // This should not happen!
        Exit("Unexpected deletion of pairing");
    }

    void PairingComplete(chip::NodeId nodeId)
    {
        MTRDeviceController * commissioner = CurrentCommissioner();
        VerifyOrReturn(commissioner != nil, Exit("No current commissioner"));

        NSError * commissionError = nil;
        [commissioner commissionNodeWithID:@(nodeId)
                       commissioningParams:[[MTRCommissioningParameters alloc] init]
                                     error:&commissionError];
        CHIP_ERROR err = MTRErrorToCHIPErrorCode(commissionError);
        if (err != CHIP_NO_ERROR) {
            Exit("Failed to kick off commissioning", err);
            return;
        }
    }

protected:
    dispatch_queue_t _Nullable mCallbackQueue;

    void Wait()
    {
        if (mDelayInMs.HasValue()) {
            chip::test_utils::SleepMillis(mDelayInMs.Value());
        }
    };

    chip::Optional<uint64_t> mDelayInMs;
    chip::Optional<char *> mPICSFilePath;
    chip::Optional<chip::EndpointId> mEndpointId;
    chip::Optional<uint16_t> mTimeout;

    bool CheckConstraintStartsWith(
        const char * _Nonnull itemName, const NSString * _Nonnull current, const char * _Nonnull expected)
    {
        const chip::CharSpan value([current UTF8String], [current lengthOfBytesUsingEncoding:NSUTF8StringEncoding]);
        return ConstraintsChecker::CheckConstraintStartsWith(itemName, value, expected);
    }

    bool CheckConstraintEndsWith(const char * _Nonnull itemName, const NSString * _Nonnull current, const char * _Nonnull expected)
    {
        const chip::CharSpan value([current UTF8String], [current lengthOfBytesUsingEncoding:NSUTF8StringEncoding]);
        return ConstraintsChecker::CheckConstraintEndsWith(itemName, value, expected);
    }

    bool CheckConstraintIsUpperCase(const char * _Nonnull itemName, const NSString * _Nonnull current, bool expectUpperCase)
    {
        const chip::CharSpan value([current UTF8String], [current lengthOfBytesUsingEncoding:NSUTF8StringEncoding]);
        return ConstraintsChecker::CheckConstraintIsUpperCase(itemName, value, expectUpperCase);
    }

    bool CheckConstraintIsLowerCase(const char * _Nonnull itemName, const NSString * _Nonnull current, bool expectLowerCase)
    {
        const chip::CharSpan value([current UTF8String], [current lengthOfBytesUsingEncoding:NSUTF8StringEncoding]);
        return ConstraintsChecker::CheckConstraintIsLowerCase(itemName, value, expectLowerCase);
    }

    bool CheckConstraintIsHexString(const char * _Nonnull itemName, const NSString * _Nonnull current, bool expectHexString)
    {
        const chip::CharSpan value([current UTF8String], [current lengthOfBytesUsingEncoding:NSUTF8StringEncoding]);
        return ConstraintsChecker::CheckConstraintIsHexString(itemName, value, expectHexString);
    }

    template <typename T> bool CheckConstraintContains(const char * _Nonnull itemName, const NSArray * _Nonnull current, T expected)
    {
        for (id currentElement in current) {
            if ([currentElement isEqualToNumber:@(expected)]) {
                return true;
            }
        }

        Exit(std::string(itemName) + " expect the value " + std::to_string(expected) + " but the list does not contains it.");
        return false;
    }

    template <typename T> bool CheckConstraintExcludes(const char * _Nonnull itemName, const NSArray * _Nonnull current, T expected)
    {
        for (id currentElement in current) {
            if ([currentElement isEqualToNumber:@(expected)]) {
                Exit(std::string(itemName) + " does not expect the value " + std::to_string(expected)
                    + " but the list contains it.");
                return false;
            }
        }

        return true;
    }

    bool CheckConstraintNotValue(
        const char * _Nonnull itemName, const NSString * _Nullable current, const NSString * _Nullable expected)
    {
        if (current == nil && expected == nil) {
            Exit(std::string(itemName) + " got unexpected value. Both values are nil.");
            return false;
        }
        if ((current == nil) != (expected == nil)) {
            return true;
        }
        const chip::CharSpan currentValue([current UTF8String], [current lengthOfBytesUsingEncoding:NSUTF8StringEncoding]);
        const chip::CharSpan expectedValue([expected UTF8String], [expected lengthOfBytesUsingEncoding:NSUTF8StringEncoding]);
        return ConstraintsChecker::CheckConstraintNotValue(itemName, currentValue, expectedValue);
    }

    bool CheckConstraintNotValue(
        const char * _Nonnull itemName, const NSData * _Nullable current, const NSData * _Nullable expected)
    {
        if (current == nil && expected == nil) {
            Exit(std::string(itemName) + " got unexpected value. Both values are nil.");
            return false;
        }
        if ((current == nil) != (expected == nil)) {
            return true;
        }
        const chip::ByteSpan currentValue(static_cast<const uint8_t *>([current bytes]), [current length]);
        const chip::ByteSpan expectedValue(static_cast<const uint8_t *>([expected bytes]), [expected length]);
        return ConstraintsChecker::CheckConstraintNotValue(itemName, currentValue, expectedValue);
    }

    bool CheckConstraintNotValue(const char * _Nonnull itemName, const NSNumber * _Nullable current, NSNumber * _Nullable expected)
    {
        if (current == nil && expected == nil) {
            Exit(std::string(itemName) + " got unexpected value. Both values are nil.");
            return false;
        }
        if ((current == nil) != (expected == nil)) {
            return true;
        }
        if ([current isEqualToNumber:expected]) {
            Exit(std::string(itemName) + " got unexpected value: " + std::string([[current stringValue] UTF8String]));
            return false;
        }

        return true;
    }

    template <typename T>
    bool CheckConstraintNotValue(const char * _Nonnull itemName, const NSNumber * _Nullable current, T expected)
    {
        return CheckConstraintNotValue(itemName, current, @(expected));
    }

    template <typename T> bool CheckConstraintNotValue(const char * _Nonnull itemName, NSError * _Nullable current, T expected)
    {
        NSNumber * currentValue = @(MTRErrorToCHIPErrorCode(current).AsInteger());
        return CheckConstraintNotValue(itemName, currentValue, @(expected));
    }

    using ConstraintsChecker::CheckConstraintMinLength;

    bool CheckConstraintMinLength(const char * _Nonnull itemName, NSString * _Nonnull current, uint64_t expected)
    {
        return CheckConstraintMinLength(itemName, [current length], expected);
    }

    bool CheckConstraintMinLength(const char * _Nonnull itemName, NSArray * _Nonnull current, uint64_t expected)
    {
        return CheckConstraintMinLength(itemName, [current count], expected);
    }

    using ConstraintsChecker::CheckConstraintMaxLength;

    bool CheckConstraintMaxLength(const char * _Nonnull itemName, NSString * _Nonnull current, uint64_t expected)
    {
        return CheckConstraintMaxLength(itemName, [current length], expected);
    }

    bool CheckConstraintMaxLength(const char * _Nonnull itemName, NSArray * _Nonnull current, uint64_t expected)
    {
        return CheckConstraintMaxLength(itemName, [current count], expected);
    }

    using ConstraintsChecker::CheckConstraintMinValue;

    // Used when the minValue is a saved variable, since ConstraintsChecker does
    // not expect Core Foundation types.
    template <typename T, std::enable_if_t<std::is_signed<T>::value, int> = 0>
    bool CheckConstraintMinValue(const char * _Nonnull itemName, T current, const NSNumber * _Nonnull expected)
    {
        return ConstraintsChecker::CheckConstraintMinValue(itemName, current, [expected longLongValue]);
    }

    template <typename T, std::enable_if_t<!std::is_signed<T>::value, int> = 0>
    bool CheckConstraintMinValue(const char * _Nonnull itemName, T current, const NSNumber * _Nonnull expected)
    {
        return ConstraintsChecker::CheckConstraintMinValue(itemName, current, [expected unsignedLongLongValue]);
    }

    using ConstraintsChecker::CheckConstraintMaxValue;

    // Used when the maxValue is a saved variable, since ConstraintsChecker does
    // not expect Core Foundation types.
    template <typename T, std::enable_if_t<std::is_signed<T>::value, int> = 0>
    bool CheckConstraintMaxValue(const char * _Nonnull itemName, T current, const NSNumber * _Nonnull expected)
    {
        return ConstraintsChecker::CheckConstraintMaxValue(itemName, current, [expected longLongValue]);
    }

    template <typename T, std::enable_if_t<!std::is_signed<T>::value, int> = 0>
    bool CheckConstraintMaxValue(const char * _Nonnull itemName, T current, const NSNumber * _Nonnull expected)
    {
        return ConstraintsChecker::CheckConstraintMaxValue(itemName, current, [expected unsignedLongLongValue]);
    }

    bool CheckConstraintHasValue(const char * _Nonnull itemName, id _Nullable current, bool shouldHaveValue)
    {
        if (shouldHaveValue && (current == nil)) {
            Exit(std::string(itemName) + " expected to have a value but doesn't");
            return false;
        }

        if (!shouldHaveValue && (current != nil)) {
            Exit(std::string(itemName) + " not expected to have a value but does");
            return false;
        }

        return true;
    }

    bool CheckValueAsString(const char * _Nonnull itemName, const id _Nonnull current, const NSString * _Nonnull expected)
    {
        NSString * data = current;
        const chip::CharSpan currentValue([data UTF8String], [data lengthOfBytesUsingEncoding:NSUTF8StringEncoding]);
        const chip::CharSpan expectedValue([expected UTF8String], [expected lengthOfBytesUsingEncoding:NSUTF8StringEncoding]);
        return ValueChecker::CheckValueAsString(itemName, currentValue, expectedValue);
    }

    bool CheckValueAsString(const char * _Nonnull itemName, const id _Nonnull current, const NSData * _Nonnull expected)
    {
        NSData * data = current;
        const chip::ByteSpan currentValue(static_cast<const uint8_t *>([data bytes]), [data length]);
        const chip::ByteSpan expectedValue(static_cast<const uint8_t *>([expected bytes]), [expected length]);
        return ValueChecker::CheckValueAsString(itemName, currentValue, expectedValue);
    }

    bool CheckValue(const char * _Nonnull itemName, NSNumber * _Nonnull current, NSNumber * _Nonnull expected)
    {
        if (![current isEqualToNumber:expected]) {
            Exit(std::string(itemName) + " value mismatch: expected " + std::string([[expected stringValue] UTF8String])
                + " but got " + std::string([[current stringValue] UTF8String]));
            return false;
        }

        return true;
    }

    bool CheckValue(const char * _Nonnull itemName, id _Nonnull current, NSNumber * _Nonnull expected)
    {
        NSNumber * currentValue = current;
        return CheckValue(itemName, currentValue, expected);
    }

    template <typename T> bool CheckValue(const char * _Nonnull itemName, NSNumber * _Nonnull current, T expected)
    {
        return CheckValue(itemName, current, @(expected));
    }

    template <typename T> bool CheckValue(const char * _Nonnull itemName, id _Nonnull current, T expected)
    {
        NSNumber * currentValue = current;
        return CheckValue(itemName, currentValue, @(expected));
    }

    template <typename T> bool CheckValue(const char * _Nonnull itemName, NSError * _Nullable current, T expected)
    {

        NSNumber * currentValue = @(current.code);
        return CheckValue(itemName, currentValue, @(expected));
    }

    template <typename T, typename U> bool CheckValue(const char * _Nonnull itemName, T current, U expected)
    {

        return ValueChecker::CheckValue(itemName, current, expected);
    }

    bool CheckValueNonNull(const char * _Nonnull itemName, id _Nullable current)
    {
        if (current != nil) {
            return true;
        }

        Exit(std::string(itemName) + " expected to not be null but is");
        return false;
    }

    bool CheckValueNull(const char * _Nonnull itemName, id _Nullable current)
    {
        if (current == nil) {
            return true;
        }

        Exit(std::string(itemName) + " expected to be null but isn't");
        return false;
    }

private:
    TestDeviceControllerDelegate * _Nonnull mDeviceControllerDelegate;

    // Set of our connected devices, keyed by identity.
    std::map<std::string, MTRBaseDevice *> mConnectedDevices;
};

NS_ASSUME_NONNULL_BEGIN

@implementation TestDeviceControllerDelegate
- (void)controller:(MTRDeviceController *)controller statusUpdate:(MTRCommissioningStatus)status
{
    if (_active) {
        if (status == MTRCommissioningStatusSuccess) {
            NSLog(@"Secure pairing success");
        } else if (status == MTRCommissioningStatusFailed) {
            _active = NO;
            NSLog(@"Secure pairing failed");
            _commandBridge->OnStatusUpdate(chip::app::StatusIB(chip::Protocols::InteractionModel::Status::Failure));
        }
    }
}

- (void)controller:(MTRDeviceController *)controller commissioningSessionEstablishmentDone:(NSError * _Nullable)error
{
    if (_active) {
        if (error != nil) {
            _active = NO;
            NSLog(@"Pairing complete with error");
            CHIP_ERROR err = MTRErrorToCHIPErrorCode(error);
            _commandBridge->OnStatusUpdate([self convertToStatusIB:err]);
        } else {
            _commandBridge->PairingComplete(_deviceId);
        }
    }
}

- (void)controller:(MTRDeviceController *)controller commissioningComplete:(NSError * _Nullable)error
{
    if (_active) {
        _active = NO;
        CHIP_ERROR err = MTRErrorToCHIPErrorCode(error);
        _commandBridge->OnStatusUpdate([self convertToStatusIB:err]);
    }
}

- (chip::app::StatusIB)convertToStatusIB:(CHIP_ERROR)err
{
    using chip::app::StatusIB;
    using namespace chip;
    using namespace chip::Protocols::InteractionModel;
    using namespace chip::app::Clusters::OperationalCredentials;

    if (CHIP_ERROR_INVALID_PUBLIC_KEY == err) {
        return StatusIB(Status::Failure, to_underlying(NodeOperationalCertStatusEnum::kInvalidPublicKey));
    }
    if (CHIP_ERROR_WRONG_NODE_ID == err) {
        return StatusIB(Status::Failure, to_underlying(NodeOperationalCertStatusEnum::kInvalidNodeOpId));
    }
    if (CHIP_ERROR_UNSUPPORTED_CERT_FORMAT == err) {
        return StatusIB(Status::Failure, to_underlying(NodeOperationalCertStatusEnum::kInvalidNOC));
    }
    if (CHIP_ERROR_FABRIC_EXISTS == err) {
        return StatusIB(Status::Failure, to_underlying(NodeOperationalCertStatusEnum::kFabricConflict));
    }
    if (CHIP_ERROR_INVALID_FABRIC_INDEX == err) {
        return StatusIB(Status::Failure, to_underlying(NodeOperationalCertStatusEnum::kInvalidFabricIndex));
    }

    return StatusIB(err);
}

- (instancetype)initWithTestCommandBridge:(TestCommandBridge *)commandBridge
{
    if (!(self = [super init])) {
        return nil;
    }

    _commandBridge = commandBridge;
    _active = NO;
    return self;
}
@end

NS_ASSUME_NONNULL_END
