// SPDX-FileCopyrightText: © 2021 Matthias Andreas Benkard <code@mail.matthias.benkard.de>
//
// SPDX-License-Identifier: LGPL-3.0-or-later

package eu.mulk.jgvariant.ostree;

import eu.mulk.jgvariant.core.Decoder;
import java.util.Arrays;
import java.util.Base64;
import java.util.HexFormat;
import java.util.stream.IntStream;
import java.util.stream.Stream;
import org.jetbrains.annotations.Nullable;

/**
 * A wrapper for a {@code byte[]} that implements {@link #equals(Object)}, {@link #hashCode()}, and
 * {@link #toString()} according to value semantics.
 *
 * @param bytes the byte array that this ByteString wraps.
 */
public record ByteString(byte[] bytes) {

  private static final Decoder<ByteString> DECODER = Decoder.ofByteArray().map(ByteString::new);

  /**
   * Returns a decoder for a {@code byte[]} that wraps the result in {@link ByteString}.
   *
   * @return a possibly shared {@link Decoder}.
   */
  public static Decoder<ByteString> decoder() {
    return DECODER;
  }

  @Override
  public boolean equals(@Nullable Object o) {
    return (o instanceof ByteString byteString) && Arrays.equals(bytes, byteString.bytes);
  }

  @Override
  public int hashCode() {
    return Arrays.hashCode(bytes);
  }

  @Override
  public String toString() {
    return "ByteString{hex=\"%s\"}".formatted(hex());
  }

  /**
   * Converts the contained byte array into a hex string.
   *
   * <p>Useful for printing.
   *
   * @return a hex string representation of this byte string.
   */
  public String hex() {
    return HexFormat.of().formatHex(bytes);
  }

  /**
   * Parses a hex string into a {@link ByteString}.
   *
   * @param hex a hex string.
   * @return a {@link ByteString} corresponding to the given hex string.
   */
  public static ByteString ofHex(String hex) {
    return new ByteString(HexFormat.of().parseHex(hex));
  }

  /**
   * Converts the contained byte array into modified Base64 (with {@code "/"} replaced with {@code
   * "-"}).
   *
   * <p>Modified Base64 is Base64 with {@code "/"} replaced with {@code "_"}. It is used to address
   * static deltas in an OSTree repository.
   *
   * <p>Useful for printing.
   *
   * @return a modified Base64 representation of the bytes making up this checksum.
   */
  public String modifiedBase64() {
    return Base64.getEncoder().withoutPadding().encodeToString(bytes).replace('/', '_');
  }

  /**
   * Parses a modified Base64 string into a {@link Checksum}.
   *
   * <p>Modified Base64 is Base64 with {@code "/"} replaced with {@code "_"}. It is used to address
   * static deltas in an OSTree repository.
   *
   * @param mbase64 a hex string.
   * @return a {@link Checksum} corresponding to the given modified Base64 string.
   */
  public static ByteString ofModifiedBase64(String mbase64) {
    return new ByteString(Base64.getDecoder().decode(mbase64.replace('_', '/')));
  }

  /**
   * Returns the number of bytes in the byte string.
   *
   * @return the number of bytes in the byte string.
   */
  public int size() {
    return bytes.length;
  }

  /**
   * Returns a {@link Stream} of all the bytes in the byte string.
   *
   * @return a new {@link Stream}.
   */
  Stream<Byte> stream() {
    return IntStream.range(0, bytes.length).mapToObj(i -> bytes[i]);
  }
}
