// Copyright 2026 Google LLC
//
// 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
//
//    https://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 THIRD_PARTY_CREDENTIO_CRYPTO_DEFAULT_CMS_BER_PARSER_H_
#define THIRD_PARTY_CREDENTIO_CRYPTO_DEFAULT_CMS_BER_PARSER_H_

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

#include "absl/strings/string_view.h"
#include "crypto/default/cms/cms_error_code.h"
#include "openssl/bytestring.h"

namespace credentio_cms {

// Zero copy ASN.1 parser supporting the minimum amount of BER encoding needed
// to work with the S/MIME clients targeted.
//
// This parser reads the elements in the order they appear, when a constructed
// element is read, the next element will be read from its value.
//
// Example if the data contains this:
// SEQUENCE
//   INTEGER 1
//   OCTECT_STRING 'foo'
// SET
// ...
// The elements read will be in order: SEQUENCE, INTEGER, OCTET_STRING,
// SET.
//
// Error handling: the parser keeps track of the first error. Once an error
// is encountered all the functions will effectively be no-op.
// This allows the caller to postpone error checking until the end of the
// parsing and makes the code easier to read.
class BerParser {
 public:
  // The data must be valid for the life of the BerParser object.
  BerParser(const uint8_t* data, size_t length);

  // Returns true if the parsing is successful, or false if there was an error.
  // Errors are sticky and once the parser encounters an error (or SetError is
  // called).
  bool ok() const;

  // Returns the current status.
  ErrorCode status() const;

  // Returns the text for the error, if any.
  std::string error_message() const;

  // Checks that the next element has the expected tag and read it.
  // If the element is constructed the parser will read from its value until
  // EndConstructedElement is called.
  // If the next element does not match an error will be set and ok() will
  // always return false.
  void GetTag(unsigned expected_tag);

  // If the next element has a tag equals to expected_tag this function behaves
  // like GetTag, otherwise it is a no-op.
  // Returns true if the expected_tag was found and read.
  bool GetOptionalTag(unsigned expected_tag);

  // If the next element has a tag equal to expected_tag, read it and make
  // 'out' point to the element value, otherwise set an error condition and
  // clear the 'out' parameter.
  // If the element is constructed the parser will read from its value until
  // EndConstructedElement is called.
  //
  // Restriction: the element must have a definite length.
  void GetElementData(unsigned expected_tag, CBS* out);

  // If the next element has a tag equal to 'expected_tag' this function behaves
  // like GetElementData, otherwise it is a no-op
  bool GetOptionalElementData(unsigned expected_tag, CBS* out);

  // Indicate that parsing is done for the current constructed element, check
  // that there is no data left in it and keep reading from its siblings.
  // If the current constructed element had an indefinite length, also check for
  // the end of content marker.
  void EndConstructed();

  // Read the next element regardless of its tag and put the header and data in
  // the 'out' parameter. Its contents will be skipped even if it is a
  // constructed element (so no need to call EndConstructedElement).
  // Restriction: the element must have a definite length.
  void GetAnyElementAndSkipChildren(CBS* out);

  // Returns true if there is no error and the next element matches the
  // expected tag.
  bool Peek(unsigned expected_tag) const;

  // Returns the offset of the current tag byte relative to the start of the
  // 'data' passed in the constructor.
  size_t GetCurrentOffset();

  // Returns true if:
  // - The next element has the NULL type (the null will be consumed).
  // - The current parsing scope is empty (reached the end of the data).
  // - The next element is the End Of Content marker and the scope was an
  //   indefinite length element.
  // - There was an earlier parsing error (to indicate that nothing more
  //   will be read).
  bool IsNullOrEmpty();

  // Checks that the next element has an INTEGER tag and its value fits in an
  // int. The element is consumed.
  // If there is an error return zero.
  int GetInt();

  // The text passed in will be added to the error message if an error happens
  // in the current parsing context.
  // This has no effect on parsing but allows error messages to be more
  // informative.
  void SetElementName(absl::string_view text);

  // If the parser is not already in an error state, this will set the internal
  // status and build an error message using 'text' and appending the byte
  // offset and scope chain.
  // If 'status' is OK this function is no-op (i.e. it doesn't clear existing
  // errors).
  void SetError(ErrorCode status, absl::string_view text);

 private:
  struct Scope {
    Scope(const CBS& data, bool indefinite)
        : data(data), indefinite(indefinite) {}
    // If this is the first stack level it points to the complete data.
    // If we are currently parsing a constructed element value, if indefinite_
    // is false it contains the element value, otherwise it contains all the
    // data that is left to parse.
    CBS data;
    // Indicates if 'data' belongs to a definite or indefinite length
    // constructed element.
    bool indefinite = false;
    // Used to provide more useful error messages.
    std::string element_name;
  };

  // Sets out data to nullptr and its length to 0.
  // Returns false if an error occurred.
  bool IsValid(CBS* out);

  // Returns true if the next two bytes are 0,0 (ASN.1 End Of Content), does not
  // consume the EOC marker.
  bool IsEndOfContent();

  // Reads the next element.
  // - out_tag will contain the tag value read.
  // - raw_tag: if it is false and the element is constructed, a new scope will
  //   be pushed and the next tags will be read from its value. If it is true
  //   the element value will be skipped by the parser.
  // - out_value will be set to the element data if it is not null.
  // - out_value will be set to the element header and data if it is not null.
  void GetTagInternal(unsigned* out_tag, CBS* out_value,
                      CBS* out_header_and_value, bool raw_tag);

  // Calls SetError if tag != expected_tag and clears out if it is not null.
  void CompareTag(unsigned tag, unsigned expected_tag, CBS* out);

  std::string error_message_;
  ErrorCode status_ = ErrorCode::OK;
  // Contains the start of the data being parsed, only used to show offsets in
  // error messages.
  const uint8_t* start_;
  // Each time a constructed tag is entered a new scope is pushed. If the length
  // is indefinite the data contains all the remaining data.
  // Each time CloseTag is called, a scope is popped, if the length was
  // indefinite the next read will start right after the scope just popped.
  std::vector<Scope> scopes_;
};

}  // namespace credentio_cms

#endif  // THIRD_PARTY_CREDENTIO_CRYPTO_DEFAULT_CMS_BER_PARSER_H_
