/*
 * 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.tuweni.crypto.sodium;

import org.apache.tuweni.bytes.Bytes;

import java.util.Objects;
import javax.security.auth.Destroyable;

import jnr.ffi.Pointer;

/**
 * Generic hashing utility (BLAKE2b).
 *
 * @see <a href="https://libsodium.gitbook.io/doc/hashing/generic_hashing">Generic hashing</a>
 *
 */
public final class GenericHash {

  /**
   * Input of generic hash function.
   */
  public static final class Input implements Destroyable {
    private final Allocated value;

    private Input(Pointer ptr, int length) {
      this.value = new Allocated(ptr, length);
    }

    @Override
    public void destroy() {
      value.destroy();
    }

    @Override
    public boolean isDestroyed() {
      return value.isDestroyed();
    }

    /**
     *
     * @return the length of the input
     */
    public int length() {
      return value.length();
    }

    /**
     * Create a {@link GenericHash.Input} from a pointer.
     *
     * @param allocated the allocated pointer
     * @return An input.
     */
    public static Input fromPointer(Allocated allocated) {
      return new Input(Sodium.dup(allocated.pointer(), allocated.length()), allocated.length());
    }

    /**
     * Create a {@link GenericHash.Input} from a hash.
     *
     * @param hash the hash
     * @return An input.
     */
    public static Input fromHash(Hash hash) {
      return new Input(Sodium.dup(hash.value.pointer(), hash.value.length()), hash.value.length());
    }

    /**
     * Create a {@link GenericHash.Input} from an array of bytes.
     *
     * @param bytes The bytes for the input.
     * @return An input.
     */
    public static Input fromBytes(Bytes bytes) {
      return fromBytes(bytes.toArrayUnsafe());
    }

    /**
     * Create a {@link GenericHash.Input} from an array of bytes.
     *
     * @param bytes The bytes for the input.
     * @return An input.
     */
    public static Input fromBytes(byte[] bytes) {
      return Sodium.dup(bytes, GenericHash.Input::new);
    }

    @Override
    public boolean equals(Object obj) {
      if (obj == this) {
        return true;
      }
      if (!(obj instanceof GenericHash.Input)) {
        return false;
      }
      Input other = (Input) obj;
      return other.value.equals(value);
    }

    @Override
    public int hashCode() {
      return Objects.hashCode(value);
    }

    /**
     * @return The bytes of this key.
     */
    public Bytes bytes() {
      return value.bytes();
    }

    /**
     * @return The bytes of this key.
     */
    public byte[] bytesArray() {
      return value.bytesArray();
    }
  }

  /**
   * Key of generic hash function.
   */
  public static final class Key implements Destroyable {
    private final Allocated value;

    private Key(Pointer ptr, int length) {
      this.value = new Allocated(ptr, length);
    }

    @Override
    public void destroy() {
      value.destroy();
    }

    @Override
    public boolean isDestroyed() {
      return value.isDestroyed();
    }

    /**
     *
     * @return the length of the key
     */
    public int length() {
      return value.length();
    }

    /**
     * Create a {@link GenericHash.Key} from a pointer.
     *
     * @param allocated the allocated pointer
     * @return A key.
     */
    public static Key fromPointer(Allocated allocated) {
      return new Key(Sodium.dup(allocated.pointer(), allocated.length()), allocated.length());
    }

    /**
     * Create a {@link GenericHash.Key} from a hash.
     *
     * @param hash the hash
     * @return A key.
     */
    public static Key fromHash(Hash hash) {
      return new Key(Sodium.dup(hash.value.pointer(), hash.value.length()), hash.value.length());
    }

    /**
     * Create a {@link GenericHash.Key} from an array of bytes.
     *
     * @param bytes The bytes for the key.
     * @return A key.
     */
    public static Key fromBytes(Bytes bytes) {
      return fromBytes(bytes.toArrayUnsafe());
    }

    /**
     * Create a {@link GenericHash.Key} from an array of bytes.
     *
     * @param bytes The bytes for the key.
     * @return A key.
     */
    public static Key fromBytes(byte[] bytes) {
      return Sodium.dup(bytes, GenericHash.Key::new);
    }

    @Override
    public boolean equals(Object obj) {
      if (obj == this) {
        return true;
      }
      if (!(obj instanceof GenericHash.Key)) {
        return false;
      }
      Key other = (Key) obj;
      return other.value.equals(value);
    }

    @Override
    public int hashCode() {
      return Objects.hashCode(value);
    }

    /**
     * @return The bytes of this key.
     */
    public Bytes bytes() {
      return value.bytes();
    }

    /**
     * @return The bytes of this key.
     */
    public byte[] bytesArray() {
      return value.bytesArray();
    }
  }

  /**
   * Generic hash function output.
   */
  public static final class Hash implements Destroyable {
    Allocated value;

    Hash(Pointer ptr, int length) {
      this.value = new Allocated(ptr, length);
    }


    @Override
    public void destroy() {
      value.destroy();
    }

    @Override
    public boolean isDestroyed() {
      return value.isDestroyed();
    }

    @Override
    public boolean equals(Object obj) {
      if (obj == this) {
        return true;
      }
      if (!(obj instanceof GenericHash.Hash)) {
        return false;
      }
      GenericHash.Hash other = (GenericHash.Hash) obj;
      return other.value.equals(value);
    }

    @Override
    public int hashCode() {
      return Objects.hashCode(value);
    }

    /**
     * Obtain the bytes of this hash.
     *
     * WARNING: This will cause the hash to be copied into heap memory.
     *
     * @return The bytes of this hash.
     */
    public Bytes bytes() {
      return value.bytes();
    }

    /**
     * Obtain the bytes of this hash.
     *
     * WARNING: This will cause the hash to be copied into heap memory. The returned array should be overwritten when no
     * longer required.
     *
     * @return The bytes of this hash.
     */
    public byte[] bytesArray() {
      return value.bytesArray();
    }

    /**
     * Provide the length of this hash.
     *
     * @return the length of this hash.
     */
    public int length() {
      return value.length();
    }
  }

  /**
   * Creates a generic hash of specified length of the input
   * 
   * @param hashLength the length of the hash
   * @param input the input of the hash function
   * @return the hash of the input
   */
  public static Hash hash(int hashLength, Input input) {
    Pointer output = Sodium.malloc(hashLength);
    Sodium.crypto_generichash(output, hashLength, input.value.pointer(), input.length(), null, 0);
    return new Hash(output, hashLength);
  }

  /**
   * Creates a generic hash of specified length of the input
   *
   * @param hashLength the length of the hash
   * @param input the input of the hash function
   * @param key the key of the hash function
   * @return the hash of the input
   */
  public static Hash hash(int hashLength, Input input, Key key) {
    Pointer output = Sodium.malloc(hashLength);
    Sodium.crypto_generichash(
        output,
        hashLength,
        input.value.pointer(),
        input.length(),
        key.value.pointer(),
        key.length());
    return new Hash(output, hashLength);
  }
}
