// Copyright 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.

#include "net/der/parser.h"

#include "base/logging.h"
#include "net/der/parse_values.h"

namespace net {

namespace der {

Parser::Parser() : advance_len_(0) {
  CBS_init(&cbs_, nullptr, 0);
}

Parser::Parser(const Input& input) : advance_len_(0) {
  CBS_init(&cbs_, input.UnsafeData(), input.Length());
}

bool Parser::PeekTagAndValue(Tag* tag, Input* out) {
  CBS peeker = cbs_;
  CBS tmp_out;
  size_t header_len;
  unsigned tag_value;
  if (!CBS_get_any_asn1_element(&peeker, &tmp_out, &tag_value, &header_len) ||
      !CBS_skip(&tmp_out, header_len)) {
    return false;
  }
  advance_len_ = CBS_len(&tmp_out) + header_len;
  *tag = tag_value;
  *out = Input(CBS_data(&tmp_out), CBS_len(&tmp_out));
  return true;
}

bool Parser::Advance() {
  if (advance_len_ == 0)
    return false;
  bool ret = !!CBS_skip(&cbs_, advance_len_);
  advance_len_ = 0;
  return ret;
}

bool Parser::HasMore() {
  return CBS_len(&cbs_) > 0;
}

bool Parser::ReadRawTLV(Input* out) {
  CBS tmp_out;
  if (!CBS_get_any_asn1_element(&cbs_, &tmp_out, nullptr, nullptr))
    return false;
  *out = Input(CBS_data(&tmp_out), CBS_len(&tmp_out));
  return true;
}

bool Parser::ReadTagAndValue(Tag* tag, Input* out) {
  if (!PeekTagAndValue(tag, out))
    return false;
  CHECK(Advance());
  return true;
}

bool Parser::ReadOptionalTag(Tag tag, Input* out, bool* present) {
  if (!HasMore()) {
    *present = false;
    return true;
  }
  Tag actual_tag;
  Input value;
  if (!PeekTagAndValue(&actual_tag, &value)) {
    return false;
  }
  if (actual_tag == tag) {
    CHECK(Advance());
    *present = true;
    *out = value;
  } else {
    advance_len_ = 0;
    *present = false;
  }
  return true;
}

bool Parser::SkipOptionalTag(Tag tag, bool* present) {
  Input out;
  return ReadOptionalTag(tag, &out, present);
}

bool Parser::ReadTag(Tag tag, Input* out) {
  Tag actual_tag;
  Input value;
  if (!PeekTagAndValue(&actual_tag, &value) || actual_tag != tag) {
    return false;
  }
  CHECK(Advance());
  *out = value;
  return true;
}

bool Parser::SkipTag(Tag tag) {
  Input out;
  return ReadTag(tag, &out);
}

// Type-specific variants of ReadTag

bool Parser::ReadConstructed(Tag tag, Parser* out) {
  if (!IsConstructed(tag))
    return false;
  Input data;
  if (!ReadTag(tag, &data))
    return false;
  *out = Parser(data);
  return true;
}

bool Parser::ReadSequence(Parser* out) {
  return ReadConstructed(kSequence, out);
}

bool Parser::ReadUint8(uint8_t* out) {
  Input encoded_int;
  if (!ReadTag(kInteger, &encoded_int))
    return false;
  return ParseUint8(encoded_int, out);
}

bool Parser::ReadUint64(uint64_t* out) {
  Input encoded_int;
  if (!ReadTag(kInteger, &encoded_int))
    return false;
  return ParseUint64(encoded_int, out);
}

bool Parser::ReadBitString(BitString* bit_string) {
  Input value;
  if (!ReadTag(kBitString, &value))
    return false;
  return ParseBitString(value, bit_string);
}

bool Parser::ReadGeneralizedTime(GeneralizedTime* out) {
  Input value;
  if (!ReadTag(kGeneralizedTime, &value))
    return false;
  return ParseGeneralizedTime(value, out);
}

}  // namespace der

}  // namespace net
