// Copyright (c) 2015 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

// This file contains data structures and utility functions used for serializing
// and parsing alternative service header values, common to HTTP/1.1 header
// fields and HTTP/2 and QUIC ALTSVC frames.  See specification at
// https://httpwg.github.io/http-extensions/alt-svc.html.

#ifndef QUICHE_SPDY_CORE_SPDY_ALT_SVC_WIRE_FORMAT_H_
#define QUICHE_SPDY_CORE_SPDY_ALT_SVC_WIRE_FORMAT_H_

#include <cstdint>
#include <string>
#include <vector>

#include "absl/container/inlined_vector.h"
#include "absl/strings/string_view.h"
#include "common/platform/api/quiche_export.h"

namespace spdy {

namespace test {
class SpdyAltSvcWireFormatPeer;
}  // namespace test

class QUICHE_EXPORT_PRIVATE SpdyAltSvcWireFormat {
 public:
  using VersionVector = absl::InlinedVector<uint32_t, 8>;

  struct QUICHE_EXPORT_PRIVATE AlternativeService {
    std::string protocol_id;
    std::string host;

    // Default is 0: invalid port.
    uint16_t port = 0;
    // Default is one day.
    uint32_t max_age = 86400;
    // Default is empty: unspecified version.
    VersionVector version;

    AlternativeService();
    AlternativeService(const std::string& protocol_id,
                       const std::string& host,
                       uint16_t port,
                       uint32_t max_age,
                       VersionVector version);
    AlternativeService(const AlternativeService& other);
    ~AlternativeService();

    bool operator==(const AlternativeService& other) const {
      return protocol_id == other.protocol_id && host == other.host &&
             port == other.port && version == other.version &&
             max_age == other.max_age;
    }
  };
  // An empty vector means alternative services should be cleared for given
  // origin.  Note that the wire format for this is the string "clear", not an
  // empty value (which is invalid).
  typedef std::vector<AlternativeService> AlternativeServiceVector;

  friend class test::SpdyAltSvcWireFormatPeer;
  static bool ParseHeaderFieldValue(absl::string_view value,
                                    AlternativeServiceVector* altsvc_vector);
  static std::string SerializeHeaderFieldValue(
      const AlternativeServiceVector& altsvc_vector);

 private:
  // Forward |*c| over space and tab or until |end| is reached.
  static void SkipWhiteSpace(absl::string_view::const_iterator* c,
                             absl::string_view::const_iterator end);
  // Decode percent-decoded string between |c| and |end| into |*output|.
  // Return true on success, false if input is invalid.
  static bool PercentDecode(absl::string_view::const_iterator c,
                            absl::string_view::const_iterator end,
                            std::string* output);
  // Parse the authority part of Alt-Svc between |c| and |end| into |*host| and
  // |*port|.  Return true on success, false if input is invalid.
  static bool ParseAltAuthority(absl::string_view::const_iterator c,
                                absl::string_view::const_iterator end,
                                std::string* host,
                                uint16_t* port);
  // Parse a positive integer between |c| and |end| into |*value|.
  // Return true on success, false if input is not a positive integer or it
  // cannot be represented on uint16_t.
  static bool ParsePositiveInteger16(absl::string_view::const_iterator c,
                                     absl::string_view::const_iterator end,
                                     uint16_t* value);
  // Parse a positive integer between |c| and |end| into |*value|.
  // Return true on success, false if input is not a positive integer or it
  // cannot be represented on uint32_t.
  static bool ParsePositiveInteger32(absl::string_view::const_iterator c,
                                     absl::string_view::const_iterator end,
                                     uint32_t* value);
  // Parse |c| as hexadecimal digit, case insensitive.  |c| must be [0-9a-fA-F].
  // Output is between 0 and 15.
  static char HexDigitToInt(char c);
  // Parse |data| as hexadecimal number into |*value|.  |data| must only contain
  // hexadecimal digits, no "0x" prefix.
  // Return true on success, false if input is empty, not valid hexadecimal
  // number, or cannot be represented on uint32_t.
  static bool HexDecodeToUInt32(absl::string_view data, uint32_t* value);
};

}  // namespace spdy

#endif  // QUICHE_SPDY_CORE_SPDY_ALT_SVC_WIRE_FORMAT_H_
