#!/bin/sh

# Determine which test to run
TEST_TYPE=${1:-"all"}

# Set to 1 to keep temporary files, 0 to clean them up
KEEP_TEMP_FILES=${2:-0}

cleanup_files() {
  if [ "$KEEP_TEMP_FILES" -eq 0 ]; then
    echo "=== CLEANING UP TEMPORARY FILES ==="
    rm -rf /test-tmp/complex /test-tmp/complex-extracted
    rm -f /test-tmp/complex-original-md5.txt /test-tmp/complex-extracted-md5.txt
    rm -rf /test-tmp/standard-test /test-tmp/standard-extracted /test-tmp/reference-extracted
    rm -f /test-tmp/original-checksums.txt /test-tmp/standard-checksums.txt /test-tmp/reference-checksums.txt
    rm -f /workdir/complex.tar.gz /workdir/standard.tar.gz /workdir/reference.tar.gz
    echo "Temporary files cleaned up"
  else
    echo "Keeping temporary files for inspection"
  fi
}

run_basic_test() {
  echo "=== RUNNING BASIC TEST ==="
  
  # Clean up existing test directories
  rm -rf /test-tmp/complex /test-tmp/complex-extracted
  rm -f /test-tmp/complex-original-md5.txt /test-tmp/complex-extracted-md5.txt

  # Create complex directory structure
  mkdir -p /test-tmp/complex/dir1/subdir1/subsubdir1
  mkdir -p /test-tmp/complex/dir1/subdir2
  mkdir -p /test-tmp/complex/dir2/subdir1

  # Create files at different levels
  echo 'root level file' > /test-tmp/complex/rootfile.txt
  echo 'level 1 file in dir1' > /test-tmp/complex/dir1/file1.txt
  echo 'level 1 file in dir2' > /test-tmp/complex/dir2/file2.txt
  echo 'level 2 file in subdir1' > /test-tmp/complex/dir1/subdir1/file3.txt
  echo 'level 2 file in subdir2' > /test-tmp/complex/dir1/subdir2/file4.txt
  echo 'level 3 file in subsubdir1' > /test-tmp/complex/dir1/subdir1/subsubdir1/file5.txt

  # Create a symbolic link with a relative path instead of absolute
  cd /test-tmp/complex/dir2 && ln -s ../rootfile.txt symlink.txt && cd /workdir

  # Calculate MD5 hashes of original files for verification
  find /test-tmp/complex -type f | sort | xargs md5sum > /test-tmp/complex-original-md5.txt

  # Print the original structure for reference
  echo '=== ORIGINAL DIRECTORY STRUCTURE ==='
  find /test-tmp/complex -type f -o -type l | sort

  # Create the tarball
  /bin/tarballer -source /test-tmp/complex -output /workdir/complex.tar.gz -prefix complex-app

  # Extract the tarball
  mkdir -p /test-tmp/complex-extracted
  tar -xzf /workdir/complex.tar.gz -C /test-tmp/complex-extracted

  # Verify the extracted structure
  echo '=== EXTRACTED DIRECTORY STRUCTURE ==='
  find /test-tmp/complex-extracted -type f -o -type l | sort

  # Calculate MD5 hashes of extracted files
  find /test-tmp/complex-extracted -type f | sort | xargs md5sum > /test-tmp/complex-extracted-md5.txt

  # Compare file content
  echo '=== VERIFYING FILE CONTENTS ==='
  cat /test-tmp/complex/rootfile.txt
  echo ' <-- Original: rootfile.txt'
  cat /test-tmp/complex-extracted/complex-app/rootfile.txt
  echo ' <-- Extracted: rootfile.txt'

  cat /test-tmp/complex/dir1/subdir1/subsubdir1/file5.txt
  echo ' <-- Original: deep nested file5.txt'
  cat /test-tmp/complex-extracted/complex-app/dir1/subdir1/subsubdir1/file5.txt
  echo ' <-- Extracted: deep nested file5.txt'

  # Test symlink
  echo '=== TESTING SYMLINK ==='
  ls -la /test-tmp/complex/dir2/symlink.txt
  ls -la /test-tmp/complex-extracted/complex-app/dir2/symlink.txt

  # Verify MD5 hashes
  echo '=== MD5 HASH VERIFICATION ==='
  echo 'Original file hashes:'
  cat /test-tmp/complex-original-md5.txt
  echo 'Extracted file hashes:'
  cat /test-tmp/complex-extracted-md5.txt

  # Verify hash comparison
  echo '=== COMPARING FILE HASHES ==='
  
  # Extract just file paths from original hashes
  ORIG_FILES=$(cat /test-tmp/complex-original-md5.txt | awk '{print $2}' | sort)
  
  # For each original file, check if its corresponding extracted file has the same hash
  ALL_MATCH=1
  for SOURCE_FILE in $ORIG_FILES; do
    # Get the base file name
    FILENAME=$(basename "$SOURCE_FILE")
    
    # Find the corresponding hash from original file
    ORIG_HASH=$(grep "$SOURCE_FILE" /test-tmp/complex-original-md5.txt | awk '{print $1}')
    
    # Find the corresponding file in the extracted directory and get its hash
    EXTRACTED_FILE=$(find /test-tmp/complex-extracted -name "$FILENAME" | head -1)
    
    if [ -z "$EXTRACTED_FILE" ]; then
      echo "ERROR: File $FILENAME not found in extracted directory"
      ALL_MATCH=0
      continue
    fi
    
    EXTRACTED_HASH=$(grep "$EXTRACTED_FILE" /test-tmp/complex-extracted-md5.txt | awk '{print $1}')
    
    if [ "$ORIG_HASH" != "$EXTRACTED_HASH" ]; then
      echo "ERROR: Hash mismatch for $FILENAME: original=$ORIG_HASH extracted=$EXTRACTED_HASH"
      ALL_MATCH=0
    fi
  done
  
  if [ "$ALL_MATCH" -eq 1 ]; then
    echo 'SUCCESS: All file hashes match between original and extracted files!'
  else
    echo 'ERROR: Hash mismatch detected!'
    return 1
  fi

  echo 'Basic test completed successfully!'
  return 0
}

run_tar_comparison_test() {
  echo "=== RUNNING TAR COMPARISON TEST ==="
  
  # Clean up test directories
  rm -rf /test-tmp/standard-test /test-tmp/standard-extracted /test-tmp/reference-extracted
  rm -f /test-tmp/original-checksums.txt /test-tmp/standard-checksums.txt /test-tmp/reference-checksums.txt

  # Create a diverse test directory structure
  mkdir -p /test-tmp/standard-test/config/settings
  mkdir -p /test-tmp/standard-test/data/user/documents
  mkdir -p /test-tmp/standard-test/data/user/pictures
  mkdir -p /test-tmp/standard-test/logs

  # Create various file types
  echo '{"app": "tarballer", "version": "1.0"}' > /test-tmp/standard-test/config/settings/app.json
  echo 'debug=true' > /test-tmp/standard-test/config/settings/debug.conf
  dd if=/dev/urandom bs=1K count=10 of=/test-tmp/standard-test/data/user/documents/binary.dat 2>/dev/null
  echo 'Test log entry 1' > /test-tmp/standard-test/logs/app.log
  echo 'Test log entry 2' >> /test-tmp/standard-test/logs/app.log

  # Create symlinks
  ln -s ../config/settings/app.json /test-tmp/standard-test/data/config-link.json
  ln -s ../../logs/app.log /test-tmp/standard-test/data/user/log-link.txt

  # Store MD5 hashes of original files for comparison
  find /test-tmp/standard-test -type f | sort | xargs md5sum > /test-tmp/original-checksums.txt

  # Create tarball using our utility
  /bin/tarballer -source /test-tmp/standard-test -output /workdir/standard.tar.gz -prefix app

  # Create a reference tarball using standard tar for comparison
  tar -czf /workdir/reference.tar.gz -C /test-tmp/standard-test --transform 's,^./,app/,' .

  echo '=== TARBALLER OUTPUT ==='
  mkdir -p /test-tmp/standard-extracted
  tar -xzf /workdir/standard.tar.gz -C /test-tmp/standard-extracted
  find /test-tmp/standard-extracted -type f -o -type l | sort

  # Extract reference tarball
  echo '=== REFERENCE TAR OUTPUT ==='
  mkdir -p /test-tmp/reference-extracted
  tar -xzf /workdir/reference.tar.gz -C /test-tmp/reference-extracted
  find /test-tmp/reference-extracted -type f -o -type l | sort

  # Verify checksums match for all extracted files
  echo '=== CHECKSUMS OF EXTRACTED FILES ==='
  find /test-tmp/standard-extracted -type f | sort | xargs md5sum > /test-tmp/standard-checksums.txt
  find /test-tmp/reference-extracted -type f | sort | xargs md5sum > /test-tmp/reference-checksums.txt

  echo 'ORIGINAL FILE CHECKSUMS:'
  cat /test-tmp/original-checksums.txt

  echo 'TARBALLER EXTRACTED CHECKSUMS:'
  cat /test-tmp/standard-checksums.txt

  echo 'REFERENCE TAR EXTRACTED CHECKSUMS:'
  cat /test-tmp/reference-checksums.txt

  # Compare MD5 checksums systematically
  echo '=== SYSTEMATIC MD5 COMPARISON ==='

  # Compare original files to tarballer extraction
  MATCH_COUNT=0
  EXPECTED_COUNT=$(cat /test-tmp/original-checksums.txt | wc -l)
  
  # For each original file, find its corresponding extracted file and compare hashes
  while read -r line; do
    ORIG_HASH=$(echo "$line" | awk '{print $1}')
    ORIG_FILE=$(echo "$line" | awk '{print $2}')
    FILENAME=$(basename "$ORIG_FILE")
    
    # Find the corresponding file in the extracted directory
    EXTRACTED_FILE=$(find /test-tmp/standard-extracted -name "$FILENAME" | grep -v ".md5-manifest.txt" | head -1)
    
    if [ -n "$EXTRACTED_FILE" ]; then
      # Get the hash of the extracted file
      EXTRACTED_HASH=$(grep "$EXTRACTED_FILE" /test-tmp/standard-checksums.txt | awk '{print $1}')
      
      if [ "$ORIG_HASH" = "$EXTRACTED_HASH" ]; then
        MATCH_COUNT=$((MATCH_COUNT + 1))
      else
        echo "Hash mismatch for $FILENAME: original=$ORIG_HASH extracted=$EXTRACTED_HASH"
      fi
    fi
  done < /test-tmp/original-checksums.txt
  
  if [ "$MATCH_COUNT" -eq "$EXPECTED_COUNT" ]; then
    echo 'SUCCESS: Tarballer extraction hashes match original files!'
  else
    echo "ERROR: Hash mismatch detected! Matched $MATCH_COUNT of $EXPECTED_COUNT files."
    return 1
  fi

  # Similar check for reference tar extraction
  MATCH_COUNT=0
  
  while read -r line; do
    ORIG_HASH=$(echo "$line" | awk '{print $1}')
    ORIG_FILE=$(echo "$line" | awk '{print $2}')
    FILENAME=$(basename "$ORIG_FILE")
    
    # Find the corresponding file in the extracted directory
    EXTRACTED_FILE=$(find /test-tmp/reference-extracted -name "$FILENAME" | head -1)
    
    if [ -n "$EXTRACTED_FILE" ]; then
      # Get the hash of the extracted file
      EXTRACTED_HASH=$(grep "$EXTRACTED_FILE" /test-tmp/reference-checksums.txt | awk '{print $1}')
      
      if [ "$ORIG_HASH" = "$EXTRACTED_HASH" ]; then
        MATCH_COUNT=$((MATCH_COUNT + 1))
      else
        echo "Hash mismatch for $FILENAME: original=$ORIG_HASH reference=$EXTRACTED_HASH"
      fi
    fi
  done < /test-tmp/original-checksums.txt
  
  if [ "$MATCH_COUNT" -eq "$EXPECTED_COUNT" ]; then
    echo 'SUCCESS: Reference tar extraction hashes match original files!'
  else
    echo "ERROR: Hash mismatch detected! Matched $MATCH_COUNT of $EXPECTED_COUNT files."
    return 1
  fi

  echo '=== VERIFYING SYMLINKS ==='
  echo 'ORIGINAL SYMLINKS:'
  find /test-tmp/standard-test -type l -exec ls -la {} \;
  echo 'EXTRACTED SYMLINKS:'
  find /test-tmp/standard-extracted -type l -exec ls -la {} \;

  # Compare file counts to ensure all files were extracted
  echo '=== FILE COUNT COMPARISON ==='
  echo -n 'Original files: ' && find /test-tmp/standard-test -type f | wc -l
  echo -n 'Extracted files: ' && find /test-tmp/standard-extracted -type f | wc -l

  # Test symlink functionality
  echo '=== TESTING SYMLINK CONTENT ==='
  echo 'Original linked content:'
  cat /test-tmp/standard-test/data/config-link.json
  echo 'Extracted linked content:'
  cat /test-tmp/standard-extracted/app/data/config-link.json

  echo 'Tar comparison test completed successfully!'
  return 0
}

# Main script execution
case "$TEST_TYPE" in
  "basic")
    run_basic_test
    RESULT=$?
    [ "$RESULT" -eq 0 ] && cleanup_files
    exit $RESULT
    ;;
  "tar")
    run_tar_comparison_test
    RESULT=$?
    [ "$RESULT" -eq 0 ] && cleanup_files
    exit $RESULT
    ;;
  "all")
    echo "=== RUNNING ALL TESTS ==="
    run_basic_test
    BASIC_RESULT=$?
    run_tar_comparison_test
    TAR_RESULT=$?
    
    if [ $BASIC_RESULT -eq 0 ] && [ $TAR_RESULT -eq 0 ]; then
      echo "✅ ALL TESTS PASSED SUCCESSFULLY!"
      cleanup_files
      exit 0
    else
      echo "❌ SOME TESTS FAILED!"
      exit 1
    fi
    ;;
  "clean")
    cleanup_files
    exit 0
    ;;
  *)
    echo "Unknown test type: $TEST_TYPE"
    echo "Usage: $0 [basic|tar|all|clean] [keep_temp_files]"
    echo "  keep_temp_files: 0 (clean up, default) or 1 (keep temp files)"
    exit 1
    ;;
esac 