// 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 "formats/id3/assessor.h"

#include <string>

#include "absl/status/status.h"
#include "absl/status/status_matchers.h"
#include "gmock/gmock.h"
#include "gtest/gtest.h"
#include "riegeli/bytes/string_reader.h"

namespace credentio {
namespace {

using ::absl_testing::IsOkAndHolds;
using ::absl_testing::StatusIs;
using ::testing::HasSubstr;

TEST(IsSupportedTest, TooFewBytes) {
  std::string audio = "\xFF";
  riegeli::StringReader<> input(audio);

  EXPECT_THAT(
      Id3Assessor().IsSupported(input),
      StatusIs(absl::StatusCode::kDataLoss, HasSubstr("kUnexpectedEof")));
}

TEST(IsSupportedTest, FalseForInvalidBeginning) {
  std::string audio = "this_is_not_a_mp3";
  riegeli::StringReader<> input(audio);

  EXPECT_THAT(Id3Assessor().IsSupported(input), IsOkAndHolds(false));
}

TEST(IsSupportedTest, ValidId3v23Header) {
  std::string audio("ID3\x03\x00\xFF\xFF\xFF", 8);
  riegeli::StringReader<> input(audio);

  EXPECT_THAT(Id3Assessor().IsSupported(input), IsOkAndHolds(true));
}

TEST(IsSupportedTest, ValidId3v24Header) {
  std::string audio("ID3\x04\x00\xFF\xFF\xFF", 8);
  riegeli::StringReader<> input(audio);

  EXPECT_THAT(Id3Assessor().IsSupported(input), IsOkAndHolds(true));
}

TEST(IsSupportedTest, ValidMp3MpegFrameHeader) {
  std::string audio = "\xFF\xF2\xFF\xFF\xFF\xFF\xFF\xFF";
  riegeli::StringReader<> input(audio);

  EXPECT_THAT(Id3Assessor().IsSupported(input), IsOkAndHolds(true));
}

TEST(IsSupportedTest, ValidFlacHeader) {
  std::string audio("fLaC\x00\x00\x00\x22", 8);
  riegeli::StringReader<> input(audio);

  EXPECT_THAT(Id3Assessor().IsSupported(input), IsOkAndHolds(true));
}

TEST(IsSupportedTest, ValidStartingBytesAtOffset2) {
  std::string audio = "ab\xFF\xF3\xFF\xFF\xFF\xFF\xFF\xFF";
  riegeli::StringReader<> input(audio);

  // Invalid at 0
  EXPECT_THAT(Id3Assessor().IsSupported(input), IsOkAndHolds(false));
  EXPECT_EQ(input.pos(), 0);

  // Valid at 2
  ASSERT_TRUE(input.Seek(2));
  EXPECT_THAT(Id3Assessor().IsSupported(input), IsOkAndHolds(true));
  EXPECT_EQ(input.pos(), 2);
}

}  // namespace
}  // namespace credentio
