/*
 *
 *    Copyright (c) 2020 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
 *          Contains the API definition for a message buffer reader for the data
 *          model.  This reader does the necessary bounds-checks before reading
 *          and updates its own state as the buffer is read.
 */

#pragma once

#include <app/util/basic-types.h>
#include <lib/core/CHIPError.h>
#include <lib/support/BufferReader.h>
#include <lib/support/CodeUtils.h>
#include <stdint.h>

namespace chip {

class DataModelReader
{
public:
    /**
     * Create a data model reader from a given buffer and length.
     *
     * @param buffer The octet buffer to read from.  The caller must ensure
     *               (most simply by allocating the reader on the stack) that
     *               the buffer outlives the reader.  The buffer is allowed to
     *               be null if buf_len is 0.
     * @param buf_len The number of octets in the buffer.
     */
    DataModelReader(const uint8_t * buffer, uint16_t buf_len) : mReader(buffer, buf_len) {}

    /**
     * Number of octets we have read so far.  This might be able to go away once
     * we do less switching back and forth between DataModelReader and raw
     * buffers.
     */
    uint16_t OctetsRead() const { return mReader.OctetsRead(); }

    /**
     * The reader status.
     */
    CHIP_ERROR StatusCode() const { return mReader.StatusCode(); }

    /**
     * Read a cluster id.
     *
     * @param [out] cluster_id Where the cluster id goes.
     *
     * @return Whether the read succeeded.  The read can fail if there are not
     *         enough octets available.
     */
    CHECK_RETURN_VALUE DataModelReader & ReadClusterId(ClusterId * cluster_id)
    {
        mReader.RawRead(cluster_id);
        return *this;
    }

    /**
     * Read an endpoint id.
     *
     * @param [out] endpoint_id Where the endpoint id goes.
     *
     * @return Whether the read succeeded.  The read can fail if there are not
     *         enough octets available.
     */
    CHECK_RETURN_VALUE DataModelReader & ReadEndpointId(EndpointId * endpoint_id)
    {
        mReader.RawRead(endpoint_id);
        return *this;
    }

    /**
     * Read a group id.
     *
     * @param [out] group_id Where the group id goes.
     *
     * @return Whether the read succeeded.  The read can fail if there are not
     *         enough octets available.
     */
    CHECK_RETURN_VALUE DataModelReader & ReadGroupId(GroupId * group_id)
    {
        mReader.RawRead(group_id);
        return *this;
    }

    /**
     * Read a single octet.
     *
     * @param [out] octet Where the octet goes.
     *
     * @return Whether the read succeeded.  The read can fail if there are not
     *         enough octets available.
     *
     * @note Use of APIs that read some semantically-meaningful type is preferred.
     */
    CHECK_RETURN_VALUE DataModelReader & ReadOctet(uint8_t * octet)
    {
        mReader.RawRead(octet);
        return *this;
    }

    /**
     * Read a single 16-bit unsigned integer.
     *
     * @param [out] dest Where the 16-bit integer goes.
     *
     * @return Whether the read succeeded.  The read can fail if there are not
     *         enough octets available.
     *
     * @note Use of APIs that read some semantically-meaningful type is preferred.
     */
    CHECK_RETURN_VALUE DataModelReader & Read16(uint16_t * dest)
    {
        mReader.RawRead(dest);
        return *this;
    }

private:
    Encoding::LittleEndian::Reader mReader;
};

} // namespace chip
