/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you 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.
 */
package org.apache.iceberg.puffin;

import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatThrownBy;

import java.io.UncheckedIOException;
import org.apache.iceberg.relocated.com.google.common.collect.ImmutableList;
import org.apache.iceberg.relocated.com.google.common.collect.ImmutableMap;
import org.junit.Test;

public class TestFileMetadataParser {
  @Test
  public void testInvalidJson() {
    assertThatThrownBy(() -> FileMetadataParser.fromJson((String) null))
        .isInstanceOf(IllegalArgumentException.class)
        .hasMessageContaining("argument \"content\" is null");

    assertThatThrownBy(() -> FileMetadataParser.fromJson(""))
        .isInstanceOf(UncheckedIOException.class)
        .hasMessageContaining("No content to map due to end-of-input");

    assertThatThrownBy(() -> FileMetadataParser.fromJson("{"))
        .isInstanceOf(UncheckedIOException.class)
        .hasMessageContaining("Unexpected end-of-input: expected close marker for Object");

    assertThatThrownBy(() -> FileMetadataParser.fromJson("{\"blobs\": []"))
        .isInstanceOf(UncheckedIOException.class)
        .hasMessageContaining("Unexpected end-of-input: expected close marker for Object");
  }

  @Test
  public void testMinimalFileMetadata() {
    testJsonSerialization(
        new FileMetadata(ImmutableList.of(), ImmutableMap.of()),
        "{\n" + "  \"blobs\" : [ ]\n" + "}");
  }

  @Test
  public void testFileProperties() {
    testJsonSerialization(
        new FileMetadata(ImmutableList.of(), ImmutableMap.of("a property", "a property value")),
        "{\n"
            + "  \"blobs\" : [ ],\n"
            + "  \"properties\" : {\n"
            + "    \"a property\" : \"a property value\"\n"
            + "  }\n"
            + "}");

    testJsonSerialization(
        new FileMetadata(
            ImmutableList.of(),
            ImmutableMap.of("a property", "a property value", "another one", "also with value")),
        "{\n"
            + "  \"blobs\" : [ ],\n"
            + "  \"properties\" : {\n"
            + "    \"a property\" : \"a property value\",\n"
            + "    \"another one\" : \"also with value\"\n"
            + "  }\n"
            + "}");
  }

  @Test
  public void testMissingBlobs() {
    assertThatThrownBy(() -> FileMetadataParser.fromJson("{\"properties\": {}}"))
        .isInstanceOf(IllegalArgumentException.class)
        .hasMessage("Cannot parse missing field: blobs");
  }

  @Test
  public void testBadBlobs() {
    assertThatThrownBy(() -> FileMetadataParser.fromJson("{\"blobs\": {}}"))
        .isInstanceOf(IllegalArgumentException.class)
        .hasMessage("Cannot parse blobs from non-array: {}");
  }

  @Test
  public void testBlobMetadata() {
    testJsonSerialization(
        new FileMetadata(
            ImmutableList.of(
                new BlobMetadata(
                    "type-a", ImmutableList.of(1), 14, 3, 4, 16, null, ImmutableMap.of()),
                new BlobMetadata(
                    "type-bbb",
                    ImmutableList.of(2, 3, 4),
                    77,
                    4,
                    Integer.MAX_VALUE * 10000L,
                    79834,
                    null,
                    ImmutableMap.of())),
            ImmutableMap.of()),
        "{\n"
            + "  \"blobs\" : [ {\n"
            + "    \"type\" : \"type-a\",\n"
            + "    \"fields\" : [ 1 ],\n"
            + "    \"snapshot-id\" : 14,\n"
            + "    \"sequence-number\" : 3,\n"
            + "    \"offset\" : 4,\n"
            + "    \"length\" : 16\n"
            + "  }, {\n"
            + "    \"type\" : \"type-bbb\",\n"
            + "    \"fields\" : [ 2, 3, 4 ],\n"
            + "    \"snapshot-id\" : 77,\n"
            + "    \"sequence-number\" : 4,\n"
            + "    \"offset\" : 21474836470000,\n"
            + "    \"length\" : 79834\n"
            + "  } ]\n"
            + "}");
  }

  @Test
  public void testBlobProperties() {
    testJsonSerialization(
        new FileMetadata(
            ImmutableList.of(
                new BlobMetadata(
                    "type-a",
                    ImmutableList.of(1),
                    14,
                    3,
                    4,
                    16,
                    null,
                    ImmutableMap.of("some key", "some value"))),
            ImmutableMap.of()),
        "{\n"
            + "  \"blobs\" : [ {\n"
            + "    \"type\" : \"type-a\",\n"
            + "    \"fields\" : [ 1 ],\n"
            + "    \"snapshot-id\" : 14,\n"
            + "    \"sequence-number\" : 3,\n"
            + "    \"offset\" : 4,\n"
            + "    \"length\" : 16,\n"
            + "    \"properties\" : {\n"
            + "      \"some key\" : \"some value\"\n"
            + "    }\n"
            + "  } ]\n"
            + "}");
  }

  @Test
  public void testFieldNumberOutOfRange() {
    assertThatThrownBy(
            () ->
                FileMetadataParser.fromJson(
                    "{\n"
                        + "  \"blobs\" : [ {\n"
                        + "    \"type\" : \"type-a\",\n"
                        + "    \"fields\" : [ "
                        + (Integer.MAX_VALUE + 1L)
                        + " ],\n"
                        + "    \"offset\" : 4,\n"
                        + "    \"length\" : 16\n"
                        + "  } ]\n"
                        + "}"))
        .isInstanceOf(IllegalArgumentException.class)
        .hasMessage("Cannot parse integer from non-int value: 2147483648");
  }

  private void testJsonSerialization(FileMetadata fileMetadata, String json) {
    assertThat(FileMetadataParser.toJson(fileMetadata, true)).isEqualTo(json);

    // Test round-trip. Note that FileMetadata doesn't implement equals()
    FileMetadata parsed = FileMetadataParser.fromJson(json);
    assertThat(FileMetadataParser.toJson(parsed, true)).isEqualTo(json);
  }
}
