// 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_seconds = 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_seconds,
                       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_seconds == other.max_age_seconds;
    }
  };
  // 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_
