// Copyright 2015 Google Inc. All Rights Reserved.
//
// 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.

#ifndef COBALT_CSP_PARSERS_H_
#define COBALT_CSP_PARSERS_H_

#include <string>
#include <utility>

#include "base/string_util.h"
#include "cobalt/csp/crypto.h"

// Utilities for parsing CSP directive headers. These emulate similar
// string helpers from Blink source.

namespace cobalt {
namespace csp {

typedef std::pair<uint32, DigestValue> HashValue;

enum ReferrerPolicy {
  // https://w3c.github.io/webappsec/specs/referrer-policy/#referrer-policy-state-unsafe-url
  kReferrerPolicyUnsafeUrl,
  // The default policy, if no policy is explicitly set by the page.
  kReferrerPolicyDefault,
  // https://w3c.github.io/webappsec/specs/referrer-policy/#referrer-policy-state-no-referrer-when-downgrade
  kReferrerPolicyNoReferrerWhenDowngrade,
  // https://w3c.github.io/webappsec/specs/referrer-policy/#referrer-policy-state-no-referrer
  kReferrerPolicyNoReferrer,
  // https://w3c.github.io/webappsec/specs/referrer-policy/#referrer-policy-state-origin
  kReferrerPolicyOrigin,
  // https://w3c.github.io/webappsec/specs/referrer-policy/#referrer-policy-state-origin-when-cross-origin
  kReferrerPolicyOriginWhenCrossOrigin,
};

enum ReflectedXSSDisposition {
  kReflectedXSSUnset = 0,
  kAllowReflectedXSS,
  kReflectedXSSInvalid,
  kFilterReflectedXSS,
  kBlockReflectedXSS
};

enum HeaderType { kHeaderTypeReport, kHeaderTypeEnforce };

enum HeaderSource {
  kHeaderSourceHTTP,
  kHeaderSourceMeta,
  kHeaderSourceMetaOutsideHead
};

inline bool SkipExactly(const char** position_ptr, const char* end,
                        char delimiter) {
  const char*& position = *position_ptr;
  if (position < end && *position == delimiter) {
    ++position;
    return true;
  }
  return false;
}

template <bool CharacterPredicate(char)>
inline bool SkipExactly(const char** position_ptr, const char* end) {
  const char*& position = *position_ptr;
  if (position < end && CharacterPredicate(*position)) {
    ++position;
    return true;
  }
  return false;
}

inline bool SkipToken(const char** position_ptr, const char* end,
                      const char* token) {
  const char*& position = *position_ptr;
  const char* current = position;
  while (current < end && *token) {
    if (*current != *token) {
      return false;
    }
    ++current;
    ++token;
  }
  if (*token) {
    return false;
  }

  position = current;
  return true;
}

inline void SkipUntil(const char** position_ptr, const char* end,
                      char delimiter) {
  const char*& position = *position_ptr;
  while (position < end && *position != delimiter) {
    ++position;
  }
}

template <bool CharacterPredicate(char)>
inline void SkipUntil(const char** position_ptr, const char* end) {
  const char*& position = *position_ptr;
  while (position < end && !CharacterPredicate(*position)) {
    ++position;
  }
}

template <bool CharacterPredicate(char)>
inline void SkipWhile(const char** position_ptr, const char* end) {
  const char*& position = *position_ptr;
  while (position < end && CharacterPredicate(*position)) {
    ++position;
  }
}

template <bool CharacterPredicate(char)>
inline void ReverseSkipWhile(const char** position_ptr, const char* start) {
  const char*& position = *position_ptr;
  while (position >= start && CharacterPredicate(*position)) {
    --position;
  }
}

inline bool IsNotAsciiWhitespace(char c) { return !IsAsciiWhitespace(c); }

inline bool IsAsciiAlphanumeric(char c) {
  return IsAsciiAlpha(c) || IsAsciiDigit(c);
}

inline bool IsCSPDirectiveNameCharacter(char c) {
  return IsAsciiAlphanumeric(c) || c == '-';
}

inline bool IsCSPDirectiveValueCharacter(char c) {
  return IsAsciiWhitespace(c) ||
         (c >= 0x21 && c <= 0x7e);  // Whitespace + VCHAR
}

// Only checks for general Base64(url) encoded chars, not '=' chars since '=' is
// positional and may only appear at the end of a Base64 encoded string.
inline bool IsBase64EncodedCharacter(char c) {
  return IsAsciiAlphanumeric(c) || c == '+' || c == '/' || c == '-' || c == '_';
}

inline bool IsNonceCharacter(char c) {
  return IsBase64EncodedCharacter(c) || c == '=';
}

inline bool IsSourceCharacter(char c) { return IsNotAsciiWhitespace(c); }

inline bool IsPathComponentCharacter(char c) { return c != '?' && c != '#'; }

inline bool IsHostCharacter(char c) {
  return IsAsciiAlphanumeric(c) || c == '-';
}

inline bool IsSchemeContinuationCharacter(char c) {
  return IsAsciiAlphanumeric(c) || c == '+' || c == '-' || c == '.';
}

inline bool IsNotColonOrSlash(char c) { return c != ':' && c != '/'; }

inline bool IsMediaTypeCharacter(char c) {
  return IsNotAsciiWhitespace(c) && c != '/';
}

static inline std::string ToString(const char* begin, const char* end) {
  return std::string(begin, static_cast<size_t>(end - begin));
}

}  // namespace csp
}  // namespace cobalt

#endif  // COBALT_CSP_PARSERS_H_
