/*
 *
 *    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.
 */

#pragma once

#include <lib/core/CHIPError.h>
#include <lib/dnssd/Resolver.h>
#include <lib/support/Span.h>
#include <system/SystemClock.h>

#include <cstddef>
#include <cstdint>

namespace chip {
namespace Dnssd {

using namespace System::Clock::Literals;

// Operational node TXT entries
static constexpr size_t kKeySessionIdleIntervalMaxLength         = 7; // [SII] 0-3600000
static constexpr size_t kKeySessionActiveIntervalMaxLength       = 7; // [SAI] 0-3600000
static constexpr size_t kKeySessionActiveThresholdMaxLength      = 5; // [SAT] 0-65535
static constexpr System::Clock::Milliseconds32 kMaxRetryInterval = 3600000_ms32;
static constexpr size_t kKeyTcpSupportedMaxLength                = 1;
static constexpr size_t kKeyLongIdleTimeICDMaxLength             = 1;

// Commissionable/commissioner node TXT entries
static constexpr size_t kKeyLongDiscriminatorMaxLength  = 5;
static constexpr size_t kKeyVendorProductMaxLength      = 11;
static constexpr size_t kKeyCommissioningModeMaxLength  = 1;
static constexpr size_t kKeyDeviceTypeMaxLength         = 10;
static constexpr size_t kKeyDeviceNameMaxLength         = 32;
static constexpr size_t kKeyRotatingDeviceIdMaxLength   = 100;
static constexpr size_t kKeyPairingInstructionMaxLength = 128;
static constexpr size_t kKeyPairingHintMaxLength        = 10;

enum class TxtKeyUse : uint8_t
{
    kNone,
    kCommon,
    kCommission,
};

enum class TxtFieldKey : uint8_t
{
    kUnknown,
    kLongDiscriminator,
    kVendorProduct,
    kCommissioningMode,
    kDeviceType,
    kDeviceName,
    kRotatingDeviceId,
    kPairingInstruction,
    kPairingHint,
    kSessionIdleInterval,
    kSessionActiveInterval,
    kSessionActiveThreshold,
    kTcpSupported,
    kLongIdleTimeICD,
    kCount,
};

namespace Internal {
struct TxtFieldInfo
{
    TxtFieldKey key;
    size_t valMaxSize;
    char keyStr[4];
    TxtKeyUse use;
};

constexpr const TxtFieldInfo txtFieldInfo[static_cast<size_t>(TxtFieldKey::kCount)] = {
    { TxtFieldKey::kUnknown, 0, "", TxtKeyUse::kNone },
    { TxtFieldKey::kLongDiscriminator, kKeyLongDiscriminatorMaxLength, "D", TxtKeyUse::kCommission },
    { TxtFieldKey::kVendorProduct, kKeyVendorProductMaxLength, "VP", TxtKeyUse::kCommission },
    { TxtFieldKey::kCommissioningMode, kKeyCommissioningModeMaxLength, "CM", TxtKeyUse::kCommission },
    { TxtFieldKey::kDeviceType, kKeyDeviceTypeMaxLength, "DT", TxtKeyUse::kCommission },
    { TxtFieldKey::kDeviceName, kKeyDeviceNameMaxLength, "DN", TxtKeyUse::kCommission },
    { TxtFieldKey::kRotatingDeviceId, kKeyRotatingDeviceIdMaxLength, "RI", TxtKeyUse::kCommission },
    { TxtFieldKey::kPairingInstruction, kKeyPairingInstructionMaxLength, "PI", TxtKeyUse::kCommission },
    { TxtFieldKey::kPairingHint, kKeyPairingHintMaxLength, "PH", TxtKeyUse::kCommission },
    { TxtFieldKey::kSessionIdleInterval, kKeySessionIdleIntervalMaxLength, "SII", TxtKeyUse::kCommon },
    { TxtFieldKey::kSessionActiveInterval, kKeySessionActiveIntervalMaxLength, "SAI", TxtKeyUse::kCommon },
    { TxtFieldKey::kSessionActiveThreshold, kKeySessionActiveThresholdMaxLength, "SAT", TxtKeyUse::kCommon },
    { TxtFieldKey::kTcpSupported, kKeyTcpSupportedMaxLength, "T", TxtKeyUse::kCommon },
    { TxtFieldKey::kLongIdleTimeICD, kKeyLongIdleTimeICDMaxLength, "ICD", TxtKeyUse::kCommon },
};
#ifdef CHIP_CONFIG_TEST

TxtFieldKey GetTxtFieldKey(const ByteSpan & key);

uint16_t GetProduct(const ByteSpan & value);
uint16_t GetVendor(const ByteSpan & value);
uint16_t GetLongDiscriminator(const ByteSpan & value);
uint8_t GetCommissioningMode(const ByteSpan & value);
uint32_t GetDeviceType(const ByteSpan & value);
void GetDeviceName(const ByteSpan & value, char * name);
void GetRotatingDeviceId(const ByteSpan & value, uint8_t * rotatingId, size_t * len);
uint16_t GetPairingHint(const ByteSpan & value);
void GetPairingInstruction(const ByteSpan & value, char * pairingInstruction);
#endif
} // namespace Internal

constexpr size_t MaxKeyLen(TxtKeyUse use)
{
    size_t max = 0;
    for (auto & info : Internal::txtFieldInfo)
    {
        if (use == info.use)
        {
            max = sizeof(info.keyStr) > max ? sizeof(info.keyStr) : max;
        }
    }
    // minus 1 because sizeof includes the null terminator.
    return max - 1;
}
constexpr size_t TotalKeyLen(TxtKeyUse use)
{
    size_t total = 0;
    for (auto & info : Internal::txtFieldInfo)
    {
        if (use == info.use)
        {
            total += sizeof(info.keyStr) - 1;
        }
    }
    return total;
}

constexpr size_t MaxValueLen(TxtKeyUse use)
{
    size_t max = 0;
    for (auto & info : Internal::txtFieldInfo)
    {
        if (use == info.use)
        {
            max = info.valMaxSize > max ? info.valMaxSize : max;
        }
    }
    // minus 1 because sizeof includes the null terminator.
    return max - 1;
}
constexpr size_t TotalValueLen(TxtKeyUse use)
{
    size_t total = 0;
    for (auto & info : Internal::txtFieldInfo)
    {
        if (use == info.use)
        {
            total += info.valMaxSize - 1;
        }
    }
    return total;
}
constexpr uint8_t KeyCount(TxtKeyUse use)
{
    uint8_t count = 0;
    for (auto & info : Internal::txtFieldInfo)
    {
        if (use == info.use)
        {
            count++;
        }
    }
    return count;
}
constexpr size_t KeySize(TxtFieldKey key)
{
    return sizeof(Internal::txtFieldInfo[static_cast<int>(key)].keyStr) - 1;
}
constexpr size_t ValSize(TxtFieldKey key)
{
    return Internal::txtFieldInfo[static_cast<int>(key)].valMaxSize;
}

void FillNodeDataFromTxt(const ByteSpan & key, const ByteSpan & value, CommonResolutionData & nodeData);
void FillNodeDataFromTxt(const ByteSpan & key, const ByteSpan & value, CommissionNodeData & nodeData);

} // namespace Dnssd
} // namespace chip
