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

#include "utils/distinguished_name.h"

#include "absl/status/status.h"
#include "absl/status/status_matchers.h"
#include "gmock/gmock.h"
#include "gtest/gtest.h"

namespace {

using ::absl_testing::IsOkAndHolds;
using ::absl_testing::StatusIs;
using ::credentio::ParseDistinguishedName;
using ::testing::IsEmpty;
using ::testing::Pair;
using ::testing::UnorderedElementsAre;

TEST(ParseDn, EmptyString) {
  EXPECT_THAT(ParseDistinguishedName(""), IsOkAndHolds(IsEmpty()));
}

TEST(ParseDn, SingleValue) {
  EXPECT_THAT(ParseDistinguishedName("CN=Foo"),
              IsOkAndHolds(UnorderedElementsAre(Pair("CN", "Foo"))));
}

TEST(ParseDn, MultipleValues) {
  EXPECT_THAT(ParseDistinguishedName("CN=Foo,O=Gizmotron,OU=Widgets Division"),
              IsOkAndHolds(UnorderedElementsAre(
                  Pair("CN", "Foo"), Pair("O", "Gizmotron"),
                  Pair("OU", "Widgets Division"))));
}

TEST(ParseDn, BackslashEscapeSequences) {
  EXPECT_THAT(ParseDistinguishedName(
                  R"(CN=Foo\2fBar\2FBaz,O=P\=NP?,OU=\57idgets Division)"),
              IsOkAndHolds(UnorderedElementsAre(
                  Pair("CN", R"(Foo/Bar/Baz)"), Pair("O", R"(P=NP?)"),
                  Pair("OU", R"(Widgets Division)"))));
}

TEST(ParseDn, TrailingBackslash) {
  EXPECT_THAT(ParseDistinguishedName(R"(CN=Foo\)"),
              StatusIs(absl::StatusCode::kInvalidArgument));
}

TEST(ParseDn, InvalidBackslashHex) {
  EXPECT_THAT(ParseDistinguishedName(R"(CN=F\9j)"),
              StatusIs(absl::StatusCode::kInvalidArgument));
}

TEST(ParseDn, UnrecognizedBackslashEscape) {
  EXPECT_THAT(ParseDistinguishedName(R"(CN=Fo\o)"),
              StatusIs(absl::StatusCode::kInvalidArgument));
}

TEST(ParseDn, MissingEquals) {
  EXPECT_THAT(ParseDistinguishedName(R"(CN=Foo,OU)"),
              StatusIs(absl::StatusCode::kInvalidArgument));
}

TEST(ParseDn, DuplicateAttribute) {
  EXPECT_THAT(ParseDistinguishedName(R"(CN=Foo,CN=Bar)"),
              StatusIs(absl::StatusCode::kInvalidArgument));
}

TEST(ParseDn, DuplicateAttributeCaseInsensitive) {
  EXPECT_THAT(ParseDistinguishedName(R"(CN=Foo,cn=Bar)"),
              StatusIs(absl::StatusCode::kInvalidArgument));
}

TEST(ParseDn, QuotedString) {
  EXPECT_THAT(
      ParseDistinguishedName(
          R"(CN="This &= That, Inc.",O="A,B,C,\58\2c\59\2c\5A\+")"),
      IsOkAndHolds(UnorderedElementsAre(Pair("CN", R"(This &= That, Inc.)"),
                                        Pair("O", R"(A,B,C,X,Y,Z+)"))));
}

TEST(ParseDn, MissingCloseQuote) {
  EXPECT_THAT(ParseDistinguishedName(R"(CN="Foo)"),
              StatusIs(absl::StatusCode::kInvalidArgument));
}

TEST(ParseDn, OidAttribute) {
  EXPECT_THAT(ParseDistinguishedName("CN=Foo,1.2.345=Bar"),
              IsOkAndHolds(UnorderedElementsAre(Pair("CN", "Foo"),
                                                Pair("1.2.345", "Bar"))));
}

TEST(ParseDn, InvalidAttributeName) {
  EXPECT_THAT(ParseDistinguishedName(".CN=Foo"),
              StatusIs(absl::StatusCode::kInvalidArgument));
}

TEST(ParseDn, HexString) {
  EXPECT_THAT(ParseDistinguishedName("CN=#466f6F"),
              IsOkAndHolds(UnorderedElementsAre(Pair("CN", "Foo"))));
}

TEST(ParseDn, HexStringOddLength) {
  EXPECT_THAT(ParseDistinguishedName("CN=#466f6"),
              StatusIs(absl::StatusCode::kInvalidArgument));
}

TEST(ParseDn, EmptyAttributeValues) {
  EXPECT_THAT(ParseDistinguishedName(R"(CN=,OU="",O=#)"),
              IsOkAndHolds(UnorderedElementsAre(Pair("CN", ""), Pair("OU", ""),
                                                Pair("O", ""))));
}

TEST(ParseDn, InvalidSeparator) {
  EXPECT_THAT(ParseDistinguishedName(R"(CN=Foo>O=Bar)"),
              StatusIs(absl::StatusCode::kInvalidArgument));
}

TEST(ParseDn, MultiValueUnsupported) {
  EXPECT_THAT(ParseDistinguishedName(R"(CN=Foo+O=Bar)"),
              StatusIs(absl::StatusCode::kUnimplemented));
}

}  // namespace
