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

/**
 *    @file
 *      This file defines the SetupDiscriminator type, which is used by
 *      low-level code (e.g. BLE) in addition to setup payload code.
 */

#pragma once

#include <lib/support/CodeUtils.h>

#include <cstdint>

namespace chip {

class SetupDiscriminator
{
public:
    constexpr SetupDiscriminator() : mDiscriminator(0), mIsShortDiscriminator(0) {}

    // See section 5.1.2. QR Code in the Matter specification
    static constexpr int kLongBits = 12;

    // See section 5.1.3. Manual Pairing Code in the Matter specification
    static constexpr int kShortBits = 4;

    void SetShortValue(uint8_t discriminator)
    {
        VerifyOrDie(discriminator == (discriminator & kShortMask));
        mDiscriminator        = (discriminator & kShortMask);
        mIsShortDiscriminator = true;
    }

    void SetLongValue(uint16_t discriminator)
    {
        VerifyOrDie(discriminator == (discriminator & kLongMask));
        mDiscriminator        = (discriminator & kLongMask);
        mIsShortDiscriminator = false;
    }

    bool IsShortDiscriminator() const { return mIsShortDiscriminator; }

    uint8_t GetShortValue() const
    {
        if (IsShortDiscriminator())
        {
            return static_cast<uint8_t>(mDiscriminator);
        }

        return LongToShortValue(mDiscriminator);
    }

    uint16_t GetLongValue() const
    {
        VerifyOrDie(!IsShortDiscriminator());
        return mDiscriminator;
    }

    bool MatchesLongDiscriminator(uint16_t discriminator) const
    {
        if (!IsShortDiscriminator())
        {
            return mDiscriminator == discriminator;
        }

        return mDiscriminator == LongToShortValue(discriminator);
    }

    bool operator==(const SetupDiscriminator & other) const
    {
        return mIsShortDiscriminator == other.mIsShortDiscriminator && mDiscriminator == other.mDiscriminator;
    }

private:
    static constexpr uint16_t kLongMask = (1 << kLongBits) - 1;
    static constexpr uint8_t kShortMask = (1 << kShortBits) - 1;

    static uint8_t LongToShortValue(uint16_t longValue)
    {
        // Short value consists of the high bits of the long value.
        constexpr int kLongToShortShift = kLongBits - kShortBits;
        return static_cast<uint8_t>(longValue >> kLongToShortShift);
    }

    // If long discriminator, all 12 bits are used.  If short discriminator,
    // only the low kShortBits bits are used, to store the value of the short
    // discriminator (which contains only the high bits of the complete 12-bit
    // discriminator).
    static_assert(kLongBits == 12, "Unexpected field length");
    static_assert(kShortBits <= kLongBits, "Unexpected field length");
    uint16_t mDiscriminator : 12;
    uint16_t mIsShortDiscriminator : 1;
};

} // namespace chip
