/*
 * Copyright (C) 2020 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.internal

import okio.ByteString
import okio.xor

internal class Hmac private constructor(
  private val hashFunction: HashFunction,
  private val outerKey: ByteArray
) : HashFunction {
  override fun update(input: ByteArray, offset: Int, byteCount: Int) {
    hashFunction.update(input, offset, byteCount)
  }

  override fun digest(): ByteArray {
    val digest = hashFunction.digest()

    hashFunction.update(outerKey)
    hashFunction.update(digest)

    return hashFunction.digest()
  }

  companion object {
    private const val IPAD: Byte = 54
    private const val OPAD: Byte = 92

    fun sha1(key: ByteString) =
      create(key, hashFunction = Sha1(), blockLength = 64)

    fun sha256(key: ByteString) =
      create(key, hashFunction = Sha256(), blockLength = 64)

    fun sha512(key: ByteString) =
      create(key, hashFunction = Sha512(), blockLength = 128)

    private fun create(
      key: ByteString,
      hashFunction: HashFunction,
      blockLength: Int
    ): Hmac {
      val keySize = key.size
      val paddedKey = when {
        keySize == 0 -> throw IllegalArgumentException("Empty key")
        keySize == blockLength -> key.data
        keySize < blockLength -> key.data.copyOf(blockLength)
        else -> hashFunction.apply { update(key.data) }.digest().copyOf(blockLength)
      }

      val innerKey = ByteArray(blockLength) { paddedKey[it] xor IPAD }
      val outerKey = ByteArray(blockLength) { paddedKey[it] xor OPAD }

      hashFunction.update(innerKey)

      return Hmac(
        hashFunction,
        outerKey
      )
    }
  }
}
