/*
 * Copyright (C) 1996-2016 The Squid Software Foundation and contributors
 *
 * Squid software is distributed under GPLv2+ license and includes
 * contributions from numerous individuals and organizations.
 * Please see the COPYING and CONTRIBUTORS files for details.
 */

#ifndef _SQUID_SRC_HELPER_REPLY_H
#define _SQUID_SRC_HELPER_REPLY_H

#include "base/CbcPointer.h"
#include "helper/forward.h"
#include "helper/ResultCode.h"
#include "MemBuf.h"
#include "Notes.h"

#include <ostream>

namespace Helper
{

/**
 * This object stores the reply message from a helper lookup
 * It provides parser routing to accept a raw buffer and process the
 * helper reply into fields for easy access by callers
 */
class Reply
{
private:
    // copy are prohibited for now
    Reply(const Helper::Reply &r);
    Reply &operator =(const Helper::Reply &r);

public:
    explicit Reply(Helper::ResultCode res = Helper::Unknown) : result(res), notes(), whichServer(NULL) {
        other_.init(1,1);
        other_.terminate();
    }

    // create/parse details from the msg buffer provided
    // XXX: buf should be const but parse() needs non-const for now
    Reply(char *buf, size_t len);

    const MemBuf &other() const { return other_; }

    /// backward compatibility:
    /// access to modifiable blob, required by redirectHandleReply()
    /// and by urlParse() in ClientRequestContext::clientRedirectDone()
    /// and by token blob/arg parsing in Negotiate auth handler
    MemBuf &modifiableOther() const { return *const_cast<MemBuf*>(&other_); }

    /** parse a helper response line format:
     *   line     := [ result ] *#( kv-pair )
     *   kv-pair := OWS token '=' ( quoted-string | token )
     *
     * token are URL-decoded.
     * quoted-string are \-escape decoded and the quotes are stripped.
     */
    // XXX: buf should be const but we may need strwordtok() and rfc1738_unescape()
    void parse(char *buf, size_t len);

public:
    /// The helper response 'result' field.
    Helper::ResultCode result;

    // list of key=value pairs the helper produced
    NotePairs notes;

    /// for stateful replies the responding helper 'server' needs to be preserved across callbacks
    CbcPointer<helper_stateful_server> whichServer;

private:
    void parseResponseKeys();

    /// the remainder of the line
    MemBuf other_;
};

} // namespace Helper

std::ostream &operator <<(std::ostream &os, const Helper::Reply &r);

#endif /* _SQUID_SRC_HELPER_REPLY_H */

