#ifndef QPID_FRAMING_FRAMESET_H
#define QPID_FRAMING_FRAMESET_H
/*
 *
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you 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.
 *
 */

#include <string>
#include "qpid/InlineVector.h"
#include "qpid/framing/amqp_framing.h"
#include "qpid/framing/AMQFrame.h"
#include "qpid/framing/SequenceNumber.h"
#include "qpid/sys/Time.h"
#include "qpid/CommonImportExport.h"

namespace qpid {
namespace framing {

/**
 * Collects the frames representing a message.
 */
class FrameSet
{
public:
    typedef InlineVector<AMQFrame, 4> Frames;

private:
    const SequenceNumber id;
    Frames parts;
    mutable uint64_t contentSize;
    mutable bool recalculateSize;
    qpid::sys::AbsTime received;

public:
    typedef boost::shared_ptr<FrameSet> shared_ptr;
    typedef Frames::iterator iterator;
    typedef Frames::const_iterator const_iterator;

    QPID_COMMON_EXTERN FrameSet(const SequenceNumber& id);
    QPID_COMMON_EXTERN FrameSet(const FrameSet&);
    QPID_COMMON_EXTERN void append(const AMQFrame& part);
    QPID_COMMON_EXTERN bool isComplete() const;

    QPID_COMMON_EXTERN uint64_t getContentSize() const;

    QPID_COMMON_EXTERN void getContent(std::string&) const;
    QPID_COMMON_EXTERN std::string getContent() const;
    QPID_COMMON_EXTERN bool hasContent() const;

    QPID_COMMON_EXTERN void setReceived();
    QPID_COMMON_EXTERN bool hasExpired() const;

    bool isContentBearing() const;

    QPID_COMMON_EXTERN const AMQMethodBody* getMethod() const;
    QPID_COMMON_EXTERN AMQMethodBody* getMethod();
    QPID_COMMON_EXTERN const AMQHeaderBody* getHeaders() const;
    QPID_COMMON_EXTERN AMQHeaderBody* getHeaders();

    template <class T> bool isA() const {
        const AMQMethodBody* method = getMethod();
        return method && method->isA<T>();
    }

    template <class T> const T* as() const {
        const AMQMethodBody* method = getMethod();
        return (method && method->isA<T>()) ? dynamic_cast<const T*>(method) : 0;
    }

    template <class T>  T* as()  {
        AMQMethodBody* method = getMethod();
        return (method && method->isA<T>()) ? dynamic_cast<T*>(method) : 0;
    }

    template <class T> const T* getHeaderProperties() const {
        const AMQHeaderBody* header = getHeaders();
        return header ? header->get<T>() : 0;
    }

    Frames::const_iterator begin() const { return parts.begin(); }
    Frames::const_iterator end() const { return parts.end(); }

    const SequenceNumber& getId() const { return id; }

    template <class P> void remove(P predicate) {
        parts.erase(std::remove_if(parts.begin(), parts.end(), predicate), parts.end());
    }

    template <class F> void map(F& functor) {
        std::for_each(parts.begin(), parts.end(), functor);
    }

    template <class F> void map(F& functor) const {
        std::for_each(parts.begin(), parts.end(), functor);
    }

    template <class F, class P> void map_if(F& functor, P predicate) {
        for(Frames::iterator i = parts.begin(); i != parts.end(); i++) {
            if (predicate(*i)) functor(*i);
        }
    }

    template <class F, class P> void map_if(F& functor, P predicate) const {
        for(Frames::const_iterator i = parts.begin(); i != parts.end(); i++) {
            if (predicate(*i)) functor(*i);
        }
    }
};

}
}


#endif /*!QPID_FRAMING_FRAMESET_H*/
