/*
 * Copyright (C) 2016 Square, Inc.
 *
 * 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
 *
 *      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 okio

import java.io.IOException
import java.security.InvalidKeyException
import java.security.MessageDigest
import javax.crypto.Mac
import javax.crypto.spec.SecretKeySpec

/**
 * A source that computes a hash of the full stream of bytes it has supplied. To use, create an
 * instance with your preferred hash algorithm. Exhaust the source by reading all of its bytes and
 * then call [hash] to compute the final hash value.
 *
 *
 * In this example we use `HashingSource` with a [BufferedSource] to make reading
 * from the source easier.
 * ```
 * HashingSource hashingSource = HashingSource.sha256(rawSource);
 * BufferedSource bufferedSource = Okio.buffer(hashingSource);
 *
 * ... // Read all of bufferedSource.
 *
 * ByteString hash = hashingSource.hash();
 * ```
 */
actual class HashingSource : ForwardingSource, Source { // Need to explicitly declare source pending fix for https://youtrack.jetbrains.com/issue/KT-20641
  private val messageDigest: MessageDigest?
  private val mac: Mac?

  internal constructor(source: Source, digest: MessageDigest) : super(source) {
    this.messageDigest = digest
    this.mac = null
  }

  internal constructor(source: Source, algorithm: String) : this(source, MessageDigest.getInstance(algorithm))

  internal constructor(source: Source, mac: Mac) : super(source) {
    this.mac = mac
    this.messageDigest = null
  }

  internal constructor(source: Source, key: ByteString, algorithm: String) : this(
    source,
    try {
      Mac.getInstance(algorithm).apply {
        init(SecretKeySpec(key.toByteArray(), algorithm))
      }
    } catch (e: InvalidKeyException) {
      throw IllegalArgumentException(e)
    }
  )

  @Throws(IOException::class)
  override fun read(sink: Buffer, byteCount: Long): Long {
    val result = super.read(sink, byteCount)

    if (result != -1L) {
      var start = sink.size - result

      // Find the first segment that has new bytes.
      var offset = sink.size
      var s = sink.head!!
      while (offset > start) {
        s = s.prev!!
        offset -= (s.limit - s.pos).toLong()
      }

      // Hash that segment and all the rest until the end.
      while (offset < sink.size) {
        val pos = (s.pos + start - offset).toInt()
        if (messageDigest != null) {
          messageDigest.update(s.data, pos, s.limit - pos)
        } else {
          mac!!.update(s.data, pos, s.limit - pos)
        }
        offset += s.limit - s.pos
        start = offset
        s = s.next!!
      }
    }

    return result
  }

  /**
   * Returns the hash of the bytes supplied thus far and resets the internal state of this source.
   *
   * **Warning:** This method is not idempotent. Each time this method is called its
   * internal state is cleared. This starts a new hash with zero bytes supplied.
   */
  @get:JvmName("hash")
  actual val hash: ByteString
    get() {
      val result = if (messageDigest != null) messageDigest.digest() else mac!!.doFinal()
      return ByteString(result)
    }

  @JvmName("-deprecated_hash")
  @Deprecated(
    message = "moved to val",
    replaceWith = ReplaceWith(expression = "hash"),
    level = DeprecationLevel.ERROR
  )
  fun hash() = hash

  actual companion object {
    /** Returns a source that uses the obsolete MD5 hash algorithm to produce 128-bit hashes. */
    @JvmStatic
    actual fun md5(source: Source) = HashingSource(source, "MD5")

    /** Returns a source that uses the obsolete SHA-1 hash algorithm to produce 160-bit hashes. */
    @JvmStatic
    actual fun sha1(source: Source) = HashingSource(source, "SHA-1")

    /** Returns a source that uses the SHA-256 hash algorithm to produce 256-bit hashes. */
    @JvmStatic
    actual fun sha256(source: Source) = HashingSource(source, "SHA-256")

    /** Returns a source that uses the SHA-512 hash algorithm to produce 512-bit hashes. */
    @JvmStatic
    actual fun sha512(source: Source) = HashingSource(source, "SHA-512")

    /** Returns a source that uses the obsolete SHA-1 HMAC algorithm to produce 160-bit hashes. */
    @JvmStatic
    actual fun hmacSha1(source: Source, key: ByteString) = HashingSource(source, key, "HmacSHA1")

    /** Returns a source that uses the SHA-256 HMAC algorithm to produce 256-bit hashes. */
    @JvmStatic
    actual fun hmacSha256(source: Source, key: ByteString) = HashingSource(source, key, "HmacSHA256")

    /** Returns a source that uses the SHA-512 HMAC algorithm to produce 512-bit hashes. */
    @JvmStatic
    actual fun hmacSha512(source: Source, key: ByteString) = HashingSource(source, key, "HmacSHA512")
  }
}
