defmodule Grizzly.ZWave.CommandClasses.S0Test do
  use ExUnit.Case, async: true

  alias Grizzly.ZWave.CommandClasses.S0

  @network_key <<0x13, 0x00, 0xA4, 0x55, 0xAE, 0x39, 0x6C, 0x0D, 0xC8, 0x11, 0x5A, 0xC9, 0x31,
                 0xC9, 0x70, 0x2D>>

  test "derives correct authentication and encryption keys from the network key" do
    expected_auth_key =
      <<0x88, 0xBD, 0x83, 0x9A, 0x89, 0x56, 0xDF, 0xAF, 0x56, 0xF2, 0xBB, 0xF8, 0x9E, 0x8A, 0x4F,
        0x66>>

    expected_enc_key =
      <<0x77, 0xE4, 0x5B, 0x47, 0xCA, 0x4B, 0x13, 0xE3, 0xC7, 0x8F, 0x2C, 0xEB, 0xAF, 0xF7, 0x3E,
        0xCE>>

    assert expected_auth_key == S0.authentication_key(@network_key)
    assert expected_enc_key == S0.encryption_key(@network_key)
  end

  test "calculates MAC correctly" do
    sender_nonce = <<0x26, 0x9F, 0x3D, 0x83, 0xBD, 0xF3, 0xF7, 0x13>>
    receiver_nonce = <<0x47, 0x9D, 0x9C, 0x79, 0xB5, 0x50, 0xF4, 0xDD>>
    encrypted_payload = <<0xB7, 0x2E, 0xCE>>

    assert <<0xD0, 0x60, 0x7A, 0x33, 0xE5, 0x27, 0x55, 0x8E>> ==
             S0.calculate_mac(
               @network_key,
               0x81,
               3,
               10,
               sender_nonce,
               receiver_nonce,
               encrypted_payload
             )
  end

  test "encrypts and decrypts a payload correctly" do
    sender_nonce = <<0x26, 0x9F, 0x3D, 0x83, 0xBD, 0xF3, 0xF7, 0x13>>
    receiver_nonce = <<0x47, 0x9D, 0x9C, 0x79, 0xB5, 0x50, 0xF4, 0xDD>>

    encrypted_payload = <<0xB7, 0x2E, 0xCE>>
    decrypted_payload = <<0x00, 0x62, 0x02>>

    assert decrypted_payload ==
             S0.decrypt(@network_key, sender_nonce, receiver_nonce, encrypted_payload)

    assert encrypted_payload ==
             S0.encrypt(@network_key, sender_nonce, receiver_nonce, decrypted_payload)
  end
end
