*** Settings ***
Library         OperatingSystem
Library         ${RSPAMD_TESTDIR}/lib/rspamd.py
Resource        ${RSPAMD_TESTDIR}/lib/rspamd.robot
Variables       ${RSPAMD_TESTDIR}/lib/vars.py

*** Variables ***
${CONFIG}                       ${RSPAMD_TESTDIR}/configs/fuzzy.conf
${FLAG1_SYMBOL}                 R_TEST_FUZZY_DENIED
${FLAG2_SYMBOL}                 R_TEST_FUZZY_WHITE
${REDIS_SCOPE}                  Suite
${RSPAMD_FLAG1_NUMBER}          50
${RSPAMD_FLAG2_NUMBER}          51
${RSPAMD_FUZZY_BACKEND}         redis
${RSPAMD_FUZZY_ENCRYPTED_ONLY}  false
${RSPAMD_FUZZY_ENCRYPTION_KEY}  null
${RSPAMD_FUZZY_INCLUDE}         ${RSPAMD_TESTDIR}/configs/empty.conf
${RSPAMD_FUZZY_KEY}             null
${RSPAMD_FUZZY_SERVER_MODE}     servers
${RSPAMD_FUZZY_SHINGLES_KEY}    null
${RSPAMD_SCOPE}                 Suite
${RSPAMD_SETTINGS_FUZZY_CHECK}         ${EMPTY}
${RSPAMD_SETTINGS_FUZZY_WORKER}        ${EMPTY}
@{MESSAGES_SKIP}                ${RSPAMD_TESTDIR}/messages/priority.eml
@{MESSAGES}                     ${RSPAMD_TESTDIR}/messages/spam_message.eml  ${RSPAMD_TESTDIR}/messages/zip.eml
@{RANDOM_MESSAGES}              ${RSPAMD_TESTDIR}/messages/bad_message.eml  ${RSPAMD_TESTDIR}/messages/zip-doublebad.eml

*** Keywords ***
Fuzzy Skip Add Test Base
  [Arguments]  ${message}
  Set Suite Variable  ${RSPAMD_FUZZY_ADD_${message}}  0
  ${result} =  Run Rspamc  -h  ${RSPAMD_LOCAL_ADDR}:${RSPAMD_PORT_CONTROLLER}  -w  10  -f
  ...  ${RSPAMD_FLAG1_NUMBER}  fuzzy_add  ${message}
  Check Rspamc  ${result}
  Sync Fuzzy Storage
  Scan File  ${message}
  Expect Symbol  R_TEST_FUZZY_DENIED
  Create File  ${RSPAMD_TMPDIR}/skip_hash.map.tmp  2d875d4737c59c4822fd01dadeba52a329de3933f766c6f167904c6a426bbfa7ea63a66bf807b25c5ee853baee58bfb18d3b423fcd13cfa7c3d77a840039a1ea
  Move File  ${RSPAMD_TMPDIR}/skip_hash.map.tmp  ${RSPAMD_TMPDIR}/skip_hash.map
  Sleep  1s  Wait for reload
  Scan File  ${message}
  Do Not Expect Symbol  R_TEST_FUZZY_DENIED

Fuzzy Add Test
  [Arguments]  ${message}
  Set Suite Variable  ${RSPAMD_FUZZY_ADD_${message}}  0
  ${result} =  Run Rspamc  -h  ${RSPAMD_LOCAL_ADDR}:${RSPAMD_PORT_CONTROLLER}  -w  10  -f
  ...  ${RSPAMD_FLAG1_NUMBER}  fuzzy_add  ${message}
  Check Rspamc  ${result}
  Sync Fuzzy Storage
  Scan File  ${message}
  Expect Symbol  ${FLAG1_SYMBOL}
  Set Suite Variable  ${RSPAMD_FUZZY_ADD_${message}}  1

Fuzzy Add Test Write Only
  [Arguments]  ${message}
  Set Suite Variable  ${RSPAMD_FUZZY_ADD_${message}}  0
  ${result} =  Run Rspamc  -h  ${RSPAMD_LOCAL_ADDR}:${RSPAMD_PORT_CONTROLLER}  -w  10  -f
  ...  ${RSPAMD_FLAG1_NUMBER}  fuzzy_add  ${message}
  Check Rspamc  ${result}
  Sync Fuzzy Storage
  # Do not scan - in write-only mode CHECK is not performed
  Set Suite Variable  ${RSPAMD_FUZZY_ADD_${message}}  1

Fuzzy Delete Test
  [Arguments]  ${message}
  IF  ${RSPAMD_FUZZY_ADD_${message}} == 0
    Fail  "Fuzzy Add was not run"
  END
  ${result} =  Run Rspamc  -h  ${RSPAMD_LOCAL_ADDR}:${RSPAMD_PORT_CONTROLLER}  -f  ${RSPAMD_FLAG1_NUMBER}  fuzzy_del
  ...  ${message}
  Check Rspamc  ${result}
  Sync Fuzzy Storage
  Scan File  ${message}
  Do Not Expect Symbol  ${FLAG1_SYMBOL}

Fuzzy Fuzzy Test
  [Arguments]  ${message}
  IF  ${RSPAMD_FUZZY_ADD_${message}} != 1
    Fail  "Fuzzy Add was not run"
  END
  @{path_info} =  Path Splitter  ${message}
  @{fuzzy_files} =  List Files In Directory  ${pathinfo}[0]  pattern=${pathinfo}[1].fuzzy*  absolute=1
  FOR  ${i}  IN  @{fuzzy_files}
    Scan File  ${i}
    Expect Symbol  ${FLAG1_SYMBOL}
  END

Fuzzy Encrypted Test
  [Arguments]  ${message}
  @{path_info} =  Path Splitter  ${message}
  @{fuzzy_files} =  List Files In Directory  ${pathinfo}[0]  pattern=${pathinfo}[1].fuzzy*  absolute=1
  FOR  ${i}  IN  @{fuzzy_files}
    ${result} =  Run Rspamc  -p  -h  ${RSPAMD_LOCAL_ADDR}:${RSPAMD_PORT_NORMAL}  --key  ${RSPAMD_FUZZY_ENCRYPTION_KEY}  ${i}
    Check Rspamc  ${result}  ${FLAG1_SYMBOL}
  END

Fuzzy Miss Test
  [Arguments]  ${message}
  Scan File  ${message}
  Do Not Expect Symbol  ${FLAG1_SYMBOL}

Fuzzy Write Only No Check Test
  [Arguments]  ${message}
  IF  ${RSPAMD_FUZZY_ADD_${message}} != 1
    Fail  "Fuzzy Add was not run"
  END
  # In write-only mode, CHECK is not sent, so symbol should not appear
  Scan File  ${message}
  Do Not Expect Symbol  ${FLAG1_SYMBOL}

Fuzzy Multi Flag Test
  [Arguments]  ${message}
  ${flag_numbers} =  Create List  ${RSPAMD_FLAG1_NUMBER}  ${RSPAMD_FLAG2_NUMBER}
  FOR  ${i}  IN  @{flag_numbers}
    ${result} =  Run Rspamc  -h  ${RSPAMD_LOCAL_ADDR}:${RSPAMD_PORT_CONTROLLER}  -w  10
    ...  -f  ${i}  fuzzy_add  ${message}
    Check Rspamc  ${result}
  END
  Sync Fuzzy Storage
  Scan File  ${message}
  Expect Symbol  ${FLAG1_SYMBOL}
  Expect Symbol  ${FLAG2_SYMBOL}

Fuzzy Multi Flag Delete Test
  [Arguments]  ${message}
  ${flag_numbers} =  Create List  ${RSPAMD_FLAG1_NUMBER}  ${RSPAMD_FLAG2_NUMBER}
  FOR  ${i}  IN  @{flag_numbers}
    ${result} =  Run Rspamc  -h  ${RSPAMD_LOCAL_ADDR}:${RSPAMD_PORT_CONTROLLER}  -w  10
    ...  -f  ${i}  fuzzy_add  ${message}
    Check Rspamc  ${result}
  END
  Sync Fuzzy Storage
  Scan File  ${message}
  Expect Symbol  ${FLAG1_SYMBOL}
  Expect Symbol  ${FLAG2_SYMBOL}
  ${result} =  Run Rspamc  -h  ${RSPAMD_LOCAL_ADDR}:${RSPAMD_PORT_CONTROLLER}  -f  ${RSPAMD_FLAG1_NUMBER}  fuzzy_del
  ...  ${message}
  Check Rspamc  ${result}
  Sync Fuzzy Storage
  Scan File  ${message}
  Do Not Expect Symbol  ${FLAG1_SYMBOL}
  Do Not Expect Symbol  ${FLAG2_SYMBOL}

Fuzzy Multimessage Multi Flag Delete Test
  FOR  ${i}  IN  @{MESSAGES}
    Fuzzy Multi Flag Delete Test  ${i}
  END

Fuzzy Setup Encrypted
  [Arguments]  ${algorithm}
  Set Suite Variable  ${RSPAMD_FUZZY_ALGORITHM}  ${algorithm}
  Set Suite Variable  ${RSPAMD_FUZZY_ENCRYPTED_ONLY}  true
  Set Suite Variable  ${RSPAMD_FUZZY_ENCRYPTION_KEY}  ${RSPAMD_KEY_PUB1}
  Set Suite Variable  ${RSPAMD_FUZZY_CLIENT_ENCRYPTION_KEY}  ${RSPAMD_KEY_PUB1}
  Set Suite Variable  ${RSPAMD_FUZZY_INCLUDE}  ${RSPAMD_TESTDIR}/configs/fuzzy-encryption-key.conf
  Set Suite Variable  ${RSPAMD_FUZZY_SERVER_MODE}  servers
  Rspamd Redis Setup

Fuzzy Setup Encrypted Dyn1
  [Arguments]  ${algorithm}
  Set Suite Variable  ${RSPAMD_FUZZY_ALGORITHM}  ${algorithm}
  Set Suite Variable  ${RSPAMD_FUZZY_ENCRYPTED_ONLY}  true
  Set Suite Variable  ${RSPAMD_FUZZY_ENCRYPTION_KEY}  ${RSPAMD_KEY_PUB1}
  Set Suite Variable  ${RSPAMD_FUZZY_CLIENT_ENCRYPTION_KEY}  ${RSPAMD_KEY_PUB2}
  Set Suite Variable  ${RSPAMD_FUZZY_INCLUDE}  ${RSPAMD_TESTDIR}/configs/fuzzy-encryption-key.conf
  Rspamd Redis Setup

Fuzzy Setup Encrypted Dyn2
  [Arguments]  ${algorithm}
  Set Suite Variable  ${RSPAMD_FUZZY_ALGORITHM}  ${algorithm}
  Set Suite Variable  ${RSPAMD_FUZZY_ENCRYPTED_ONLY}  true
  Set Suite Variable  ${RSPAMD_FUZZY_ENCRYPTION_KEY}  ${RSPAMD_KEY_PUB1}
  Set Suite Variable  ${RSPAMD_FUZZY_CLIENT_ENCRYPTION_KEY}  ${RSPAMD_KEY_PUB3}
  Set Suite Variable  ${RSPAMD_FUZZY_INCLUDE}  ${RSPAMD_TESTDIR}/configs/fuzzy-encryption-key.conf
  Rspamd Redis Setup

Fuzzy Setup Encrypted Keyed
  [Arguments]  ${algorithm}
  Set Suite Variable  ${RSPAMD_FUZZY_ALGORITHM}  ${algorithm}
  Set Suite Variable  ${RSPAMD_FUZZY_ENCRYPTED_ONLY}  true
  Set Suite Variable  ${RSPAMD_FUZZY_ENCRYPTION_KEY}  ${RSPAMD_KEY_PUB1}
  Set Suite Variable  ${RSPAMD_FUZZY_CLIENT_ENCRYPTION_KEY}  ${RSPAMD_KEY_PUB1}
  Set Suite Variable  ${RSPAMD_FUZZY_KEY}  mYN888sydwLTfE32g2hN
  Set Suite Variable  ${RSPAMD_FUZZY_SHINGLES_KEY}  hXUCgul9yYY3Zlk1QIT2
  Rspamd Redis Setup

Fuzzy Setup Plain
  [Arguments]  ${algorithm}
  Set Suite Variable  ${RSPAMD_FUZZY_ALGORITHM}  ${algorithm}
  Set Suite Variable  ${RSPAMD_FUZZY_SERVER_MODE}  servers
  Set Suite Variable  ${RSPAMD_SETTINGS_FUZZY_CHECK}  servers = "${RSPAMD_LOCAL_ADDR}:${RSPAMD_PORT_FUZZY}";
  Rspamd Redis Setup

Fuzzy Setup Keyed
  [Arguments]  ${algorithm}
  Set Suite Variable  ${RSPAMD_FUZZY_ALGORITHM}  ${algorithm}
  Set Suite Variable  ${RSPAMD_FUZZY_KEY}  mYN888sydwLTfE32g2hN
  Set Suite Variable  ${RSPAMD_FUZZY_SHINGLES_KEY}  hXUCgul9yYY3Zlk1QIT2
  Set Suite Variable  ${RSPAMD_FUZZY_SERVER_MODE}  servers
  Rspamd Redis Setup

Fuzzy Setup Plain Fasthash
  Fuzzy Setup Plain  fasthash

Fuzzy Setup Plain Mumhash
  Fuzzy Setup Plain  mumhash

Fuzzy Setup Plain Siphash
  Fuzzy Setup Plain  siphash

Fuzzy Setup Plain Xxhash
  Fuzzy Setup Plain  xxhash

Fuzzy Setup Keyed Fasthash
  Fuzzy Setup Keyed  fasthash

Fuzzy Setup Keyed Mumhash
  Fuzzy Setup Keyed  mumhash

Fuzzy Setup Keyed Siphash
  Fuzzy Setup Keyed  siphash

Fuzzy Setup Keyed Xxhash
  Fuzzy Setup Keyed  xxhash

Fuzzy Setup Encrypted Siphash
  Fuzzy Setup Encrypted  siphash

Fuzzy Setup Encrypted Dyn1 Siphash
  Fuzzy Setup Encrypted Dyn1  siphash

Fuzzy Setup Encrypted Dyn2 Siphash
  Fuzzy Setup Encrypted Dyn2  siphash

Fuzzy Skip Hash Test Message
  FOR  ${i}  IN  @{MESSAGES_SKIP}
    Fuzzy Skip Add Test Base  ${i}
  END

Fuzzy Multimessage Add Test
  FOR  ${i}  IN  @{MESSAGES}
    Fuzzy Add Test  ${i}
  END

Fuzzy Multimessage Add Test Write Only
  FOR  ${i}  IN  @{MESSAGES}
    Fuzzy Add Test Write Only  ${i}
  END

Fuzzy Multimessage Fuzzy Test
  FOR  ${i}  IN  @{MESSAGES}
    Fuzzy Fuzzy Test  ${i}
  END

Fuzzy Multimessage Fuzzy Encrypted Test
  FOR  ${i}  IN  @{MESSAGES}
    Fuzzy Encrypted Test  ${i}
  END

Fuzzy Multimessage Miss Test
  FOR  ${i}  IN  @{RANDOM_MESSAGES}
    Fuzzy Miss Test  ${i}
  END

Fuzzy Multimessage Delete Test
  FOR  ${i}  IN  @{MESSAGES}
    Fuzzy Delete Test  ${i}
  END

Fuzzy Multimessage Multi Flag Test
  FOR  ${i}  IN  @{MESSAGES}
    Fuzzy Multi Flag Test  ${i}
  END

Fuzzy Multimessage Write Only No Check Test
  FOR  ${i}  IN  @{MESSAGES}
    Fuzzy Write Only No Check Test  ${i}
  END

Fuzzy Setup Split Servers
  Set Suite Variable  ${RSPAMD_FUZZY_ALGORITHM}  siphash
  Set Suite Variable  ${RSPAMD_FUZZY_SERVER_MODE}  split
  Set Suite Variable  ${RSPAMD_SETTINGS_FUZZY_CHECK}  read_servers = "${RSPAMD_LOCAL_ADDR}:${RSPAMD_PORT_FUZZY}"; write_servers = "${RSPAMD_LOCAL_ADDR}:${RSPAMD_PORT_FUZZY}";
  Rspamd Redis Setup

Fuzzy Setup Read Only
  Set Suite Variable  ${RSPAMD_FUZZY_ALGORITHM}  siphash
  Set Suite Variable  ${RSPAMD_FUZZY_SERVER_MODE}  read_only
  Set Suite Variable  ${RSPAMD_SETTINGS_FUZZY_CHECK}  read_only = true;
  Rspamd Redis Setup

Fuzzy Setup Write Only
  Set Suite Variable  ${RSPAMD_FUZZY_ALGORITHM}  siphash
  Set Suite Variable  ${RSPAMD_FUZZY_SERVER_MODE}  write_only
  Set Suite Variable  ${RSPAMD_SETTINGS_FUZZY_CHECK}  mode = "write_only";
  Rspamd Redis Setup

Fuzzy Setup TCP
  [Arguments]  ${algorithm}
  Set Suite Variable  ${RSPAMD_FUZZY_ALGORITHM}  ${algorithm}
  Set Suite Variable  ${RSPAMD_FUZZY_SERVER_MODE}  servers
  Set Suite Variable  ${RSPAMD_SETTINGS_FUZZY_CHECK}  tcp = "auto"; tcp_threshold = 5;
  Rspamd Redis Setup

Fuzzy Setup TCP Siphash
  Fuzzy Setup TCP  siphash

Fuzzy Setup TCP Encrypted
  [Arguments]  ${algorithm}
  Set Suite Variable  ${RSPAMD_FUZZY_ALGORITHM}  ${algorithm}
  Set Suite Variable  ${RSPAMD_FUZZY_ENCRYPTED_ONLY}  true
  Set Suite Variable  ${RSPAMD_FUZZY_ENCRYPTION_KEY}  ${RSPAMD_KEY_PUB1}
  Set Suite Variable  ${RSPAMD_FUZZY_CLIENT_ENCRYPTION_KEY}  ${RSPAMD_KEY_PUB1}
  Set Suite Variable  ${RSPAMD_FUZZY_INCLUDE}  ${RSPAMD_TESTDIR}/configs/fuzzy-encryption-key.conf
  Set Suite Variable  ${RSPAMD_FUZZY_SERVER_MODE}  servers
  Set Suite Variable  ${RSPAMD_SETTINGS_FUZZY_WORKER}  tcp = true;
  Set Suite Variable  ${RSPAMD_SETTINGS_FUZZY_CHECK}  tcp = "auto"; tcp_threshold = 5;
  Rspamd Redis Setup

Fuzzy Setup TCP Encrypted Siphash
  Fuzzy Setup TCP Encrypted  siphash

Fuzzy Setup TCP Explicit
  [Arguments]  ${algorithm}
  Set Suite Variable  ${RSPAMD_FUZZY_ALGORITHM}  ${algorithm}
  Set Suite Variable  ${RSPAMD_FUZZY_SERVER_MODE}  servers
  Set Suite Variable  ${RSPAMD_SETTINGS_FUZZY_WORKER}  tcp = true;
  Set Suite Variable  ${RSPAMD_SETTINGS_FUZZY_CHECK}  tcp = "yes";
  Rspamd Redis Setup

Fuzzy Setup TCP Explicit Siphash
  Fuzzy Setup TCP Explicit  siphash

Fuzzy TCP High Rate Test
  # Send multiple messages to exceed rate threshold and trigger TCP
  FOR  ${i}  IN RANGE  10
    FOR  ${message}  IN  @{MESSAGES}
      ${result} =  Run Rspamc  -h  ${RSPAMD_LOCAL_ADDR}:${RSPAMD_PORT_CONTROLLER}  -w  10  -f
      ...  ${RSPAMD_FLAG1_NUMBER}  fuzzy_add  ${message}
      Check Rspamc  ${result}
    END
  END
  Sync Fuzzy Storage
  # Verify that fuzzy check still works
  FOR  ${message}  IN  @{MESSAGES}
    Scan File  ${message}
    Expect Symbol  ${FLAG1_SYMBOL}
  END
