// Copyright 2011 Google Inc.
//
// 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.

// Author: jmarantz@google.com (Joshua Marantz)

#ifndef PAGESPEED_KERNEL_HTTP_HEADERS_H_
#define PAGESPEED_KERNEL_HTTP_HEADERS_H_

#include <map>
#include <utility>

#include "pagespeed/kernel/base/basictypes.h"
#include "pagespeed/kernel/base/proto_util.h"
#include "pagespeed/kernel/base/scoped_ptr.h"
#include "pagespeed/kernel/base/string.h"
#include "pagespeed/kernel/base/string_util.h"

namespace net_instaweb {

class MessageHandler;
class NameValue;
class StringMultiMapInsensitive;
class Writer;

// Read/write API for HTTP headers (shared base class)
template<class Proto> class Headers {
 public:
  // typedef's for manipulating the cookie multimap.
  typedef std::pair<StringPiece, StringPiece> ValueAndAttributes;
  typedef std::multimap<StringPiece, ValueAndAttributes> CookieMultimap;
  typedef std::multimap<StringPiece, ValueAndAttributes>::const_iterator
      CookieMultimapConstIter;

  Headers();
  virtual ~Headers();

  virtual void Clear();

  int major_version() const;
  bool has_major_version() const;
  int minor_version() const;
  void set_major_version(int major_version);
  void set_minor_version(int major_version);

  // Raw access for random access to attribute name/value pairs.
  int NumAttributes() const;
  const GoogleString& Name(int i) const;
  const GoogleString& Value(int i) const;
  void SetValue(int i, StringPiece value);

  // Lookup attributes with provided name. Attribute values are stored in
  // values. Returns true iff there were any attributes with provided name.
  // Attributes that normally appear as a comma-separated header list
  // (Cache-Control, Accept, etc.) will yield multiple entries in *values.
  // Multiple occurrences of a header (Cookie, etc.) will also yield multiple
  // entries in *values.  In most cases (but not Cookies) the semantics are
  // equivalent either way.  See:
  //   http://tools.ietf.org/html/draft-ietf-httpbis-p1-messaging-26#section-3.2.2
  //
  // Note that Lookup, though declared const, is NOT thread-safe.  This
  // is because it lazily generates a map.
  // TODO(jmarantz): this is a problem waiting to happen, but I believe it
  // will not be a problem in the immediate future.  We can refactor our way
  // around this problem by moving the Map to an explicit separate class that
  // can be instantiated to assist with Lookups and Remove.  But that should
  // be done in a separate CL from the one I'm typing into now.
  bool Lookup(const StringPiece& name, ConstStringStarVector* values) const;

  // Synthesize a string that represents what all the values a header would
  // serialize to.  Returns "" if the header isn't present.
  //
  // Same constness warnings as for ResponseHeaders::Lookup() apply.
  GoogleString LookupJoined(StringPiece name) const;

  // Looks up a single attribute value.  Returns NULL if the attribute is not
  // found, or if more than one attribute is found (either multiple
  // comma-separated entries, or multiple copies of the header).
  const char* Lookup1(const StringPiece& name) const;

  // Does there exist a header with given name.
  bool Has(const StringPiece& name) const;

  // Is value one of the values in Lookup(name)?
  bool HasValue(const StringPiece& name, const StringPiece& value) const;

  // NumAttributeNames is also const but not thread-safe.
  int NumAttributeNames() const;

  // Remove all instances of cookie_name in all the cookie headers.
  // Empty cookie headers will be removed.
  // It might be better for performance if this function is called after
  // checking that the cookie is present.
  // CAVEAT: Double quoted values are not necessarily treated as one token.
  // Please refer to the test cases in headers_cookie_util_test.cc for more
  // details.
  void RemoveCookie(const StringPiece& cookie_name);

  // Adds a new header, even if a header with the 'name' exists already.  Note
  // that this does *not* add a new entry to a comma-separated list for headers
  // that are ordinarily represented that way, but that the semantics will be
  // the same.
  void Add(const StringPiece& name, const StringPiece& value);

  // Remove headers by name and value. Return true if anything was removed.
  // Note: If the original headers were:
  // attr: val1
  // attr: val2
  // attr: val3
  // and you Remove(attr, val2), your new headers will be:
  // attr: val1, val3 (if attr is a comma-separated field)
  // and -
  // attr: val1
  // attr: val3 (otherwise).
  bool Remove(const StringPiece& name, const StringPiece& value);

  // Removes all headers by name.  Return true if anything was removed.
  bool RemoveAll(const StringPiece& name);

  // Removes all headers whose name is in |names|, which must be in
  // case-insensitive sorted order.
  bool RemoveAllFromSortedArray(const StringPiece* names,
                                int names_size);

  // Removes all headers whose name is in |names|, which must be in
  // string-insensitive sorted order.  Returns true if anything was
  // removed.
  static bool RemoveFromHeaders(const StringPiece* names,
                                int names_size,
                                protobuf::RepeatedPtrField<NameValue>* headers);

  // Removes all headers whose name starts with prefix.  Returns true if
  // anything was removed.
  bool RemoveAllWithPrefix(const StringPiece& prefix);

  // Removes any headers from this that are not in 'keep', considering both
  // names and values.  Returns true if anything was removed.
  bool RemoveIfNotIn(const Headers& keep);

  // Similar to RemoveAll followed by Add.  Note that the attribute
  // order may be changed as a side effect of this operation.
  virtual void Replace(const StringPiece& name, const StringPiece& value);

  // Merge headers. Replaces all headers specified both here and in
  // other with the version in other. Useful for updating headers
  // when recieving 304 Not Modified responses.
  // Note: This is order-scrambling.
  virtual void UpdateFrom(const Headers<Proto>& other);

  // Serialize HTTP header to a binary stream.
  virtual bool WriteAsBinary(Writer* writer, MessageHandler* message_handler);

  // Read HTTP header from a binary string.
  virtual bool ReadFromBinary(const StringPiece& buf, MessageHandler* handler);

  // Serialize HTTP headers in HTTP format so it can be re-parsed
  virtual bool WriteAsHttp(Writer* writer, MessageHandler* handler) const;

  // Copy protobuf representation to "proto".
  void CopyToProto(Proto* proto) const;

  // Check the given vector of name[=value] strings for an entry with the given
  // name, returning true iff found and setting optional_retval iff it is not
  // NULL and there is a value assigned (there is an '=' in the string).
  // Note: only the value of the first occurence of name is returned.
  // Note: the return value is trimmed of leading and trailing whitespace.
  // Note: the return value might be assigned to even if we return false.
  static bool FindValueForName(const StringPieceVector& name_equals_value_vec,
                               StringPiece name_to_find,
                               StringPiece* optional_retval);

  // Parse a name[=value] string and extract the name and value (if the given
  // argument isn't NULL) with leading and trailing whitespace removed.
  // Returns true if a value was assigned (specifically, an '=' was found),
  // else false.
  static bool ExtractNameAndValue(StringPiece input, StringPiece* name,
                                  StringPiece* optional_retval);

 protected:
  // You need to know what you're doing to use these, so for subclasses only.
  void SetProto(Proto* proto);  // Takes ownership of the argument.
  void CopyProto(const Proto& proto);

  void PopulateMap() const;  // const is a lie, mutates map_.

  // Populates the cookies map and returns a const pointer to it. 'name' is
  // the name of the header to lookup: either "Cookie" for request headers or
  // "Set-Cookie" for response headers. The header is assumed to contain semi-
  // colon separated name=value pairs. For "Set-Cookie" headers, the first pair
  // is the name and value of the cookie and subsequent pairs are attributes of
  // that cookie - the value will be the 'first' part of the pair in the map,
  // all the attributes will be the 'second' part (as a single string of semi-
  // colon separated name=value pairs). For "Cookie" headers, each pair is an
  // independent cookie and is put into the map separately.
  // Note that const is a lie: cookies_ is mutated.
  const CookieMultimap* PopulateCookieMap(StringPiece header_name) const;

  // Called whenever a mutation occurrs.  Subclasses may override to update
  // any local copies of data.
  virtual void UpdateHook();

  // Subclasses need to manipulate the proto_ member as its type and use is
  // specific to the subclass.
  const Proto* proto() const { return proto_.get(); }
  Proto* mutable_proto() { return proto_.get(); }

 private:
  // If name is a comma-separated field (above), then split value at commas,
  // and add name, val for each of the comma-separated values
  // (removing whitespace and commas).
  // Otherwise, add the name, value pair to the map_.
  // const is a lie
  // NOTE: the map will contain the comma-split values, but the protobuf
  // will contain the original pairs including comma-separated values.
  void AddToMap(const StringPiece& name, const StringPiece& value) const;

  // We have two representations for the name/value pairs.  Proto contains a
  // simple string-pair vector, but lacks a fast associative lookup.  So we
  // will build structures for associative lookup lazily, and keep them
  // up-to-date if they are present.
  mutable scoped_ptr<StringMultiMapInsensitive> map_;
  scoped_ptr<Proto> proto_;

  // Furthermore, we also have a map of cookie names to <value, attributes>.
  // It is lazilyloaded by PopulateCookieMap as/when required. The keys and
  // values all point into the map_ data element. We cater for the same cookie
  // being set multiple times though we don't necessarily handle that correctly.
  mutable scoped_ptr<CookieMultimap> cookies_;

  DISALLOW_COPY_AND_ASSIGN(Headers);
};

}  // namespace net_instaweb

#endif  // PAGESPEED_KERNEL_HTTP_HEADERS_H_
