/*
 * This file is part of adventure, licensed under the MIT License.
 *
 * Copyright (c) 2017-2020 KyoriPowered
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in all
 * copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 * SOFTWARE.
 */
package net.kyori.adventure.nbt.api;

import java.io.IOException;
import net.kyori.adventure.util.Codec;
import org.checkerframework.checker.nullness.qual.NonNull;

import static java.util.Objects.requireNonNull;

/**
 * Holds a compound binary tag.
 *
 * <p>Instead of including an entire NBT implementation in Adventure, it was decided to
 * use this "holder" interface instead. This opens the door for platform specific implementations.</p>
 *
 * <p>See {@code net.kyori.adventure.nbt.impl} for a platform agnostic implementation.</p>
 */
public interface BinaryTagHolder {
  /**
   * Encodes {@code nbt} using {@code codec}.
   *
   * @param nbt the binary tag
   * @param codec the codec
   * @param <T> the binary tag type
   * @return the encoded binary tag holder
   * @throws IOException if an error occurred while encoding the binary tag
   */
  static <T> @NonNull BinaryTagHolder encode(final @NonNull T nbt, final @NonNull Codec<? super T, String, ? extends IOException, ? extends IOException> codec) throws IOException {
    return new BinaryTagHolderImpl(codec.encode(nbt));
  }

  /**
   * Creates an encoded binary tag holder.
   *
   * @param string the encoded binary tag value
   * @return the encoded binary tag
   */
  static @NonNull BinaryTagHolder of(final @NonNull String string) {
    return new BinaryTagHolderImpl(string);
  }

  /**
   * Gets the raw string value.
   *
   * @return the raw string value
   */
  @NonNull String string();

  /**
   * Gets the held value as a binary tag.
   *
   * @param codec the codec
   * @param <T> the binary tag type
   * @return the binary tag
   * @throws IOException if an error occurred while retrieving the binary tag
   */
  <T> @NonNull T get(final @NonNull Codec<T, String, IOException, IOException> codec) throws IOException;
}

/* package */ final class BinaryTagHolderImpl implements BinaryTagHolder {
  private final String string;

  /* package */ BinaryTagHolderImpl(final String string) {
    this.string = requireNonNull(string, "string");
  }

  @Override
  public @NonNull String string() {
    return this.string;
  }

  @Override
  public <T> @NonNull T get(final @NonNull Codec<T, String, IOException, IOException> codec) throws IOException {
    return codec.decode(this.string);
  }
}

@@ -1227,36 +1227,8 @@
 i;%0A%0A
-import java.io.IOException;%0A
 impo
@@ -1878,32 +1878,71 @@
 binary tag type%0A
+   * @param %3CEX%3E encode exception type%0A
    * @return the
@@ -1977,35 +1977,26 @@
   * @throws 
-IOException
+EX
  if an error
@@ -2048,24 +2048,46 @@
 %0A  static %3CT
+, EX extends Exception
 %3E @NonNull B
@@ -2175,51 +2175,12 @@
 g, ?
- extends IOException, ? extends IOException
+, EX
 %3E co
@@ -2187,35 +2187,26 @@
 dec) throws 
-IOException
+EX
  %7B%0A    retur
@@ -2743,24 +2743,70 @@
 ry tag type%0A
+   * @param %3CDX%3E decode thrown exception type%0A
    * @return
@@ -2834,27 +2834,18 @@
 @throws 
-IOException
+DX
  if an e
@@ -2900,16 +2900,38 @@
  */%0A  %3CT
+, DX extends Exception
 %3E @NonNu
@@ -2975,32 +2975,13 @@
 ng, 
-IOException, IOException
+DX, ?
 %3E co
@@ -2992,27 +2992,18 @@
  throws 
-IOException
+DX
 ;%0A%7D%0A%0A/* 
@@ -3322,16 +3322,38 @@
 ublic %3CT
+, DX extends Exception
 %3E @NonNu
@@ -3397,32 +3397,13 @@
 ng, 
-IOException, IOException
+DX, ?
 %3E co
@@ -3418,19 +3418,10 @@
 ows 
-IOException
+DX
  %7B%0A 

Make generics on BinaryTagHolder more flexible