#!/bin/bash

VERSION="1.1.0"

# Colors
RED="\e[31m"
GREEN="\e[32m"
YELLOW="\e[33m"
CYAN="\e[36m"
RESET="\e[0m"

usage() {
    echo -e "${CYAN}Usage:${RESET} hashstring <format> <password>"
    echo -e "       hashstring list"
    echo -e "       hashstring verify <format> <hash> <password>"
    echo -e "       hashstring --help"
    echo -e "       hashstring --version"
}

help() {
    echo -e "${CYAN}hashstring${RESET} - generate and verify password hashes"

    echo
    echo -e "${CYAN}Usage:${RESET}"
    echo "  hashstring <format> <password>"
    echo "      Generate a hash using the specified format."

    echo "  hashstring list"
    echo "      Show all supported hash formats."

    echo "  hashstring verify <format> <hash> <password>"
    echo "      Verify that <password> matches <hash> using <format>."

    echo "  hashstring --help"
    echo "      Show this help message."

    echo "  hashstring --version"
    echo "      Show version information."

    echo
    echo -e "${CYAN}Supported Formats:${RESET}"
    echo "  bcrypt"
    echo "  sha256"
    echo "  sha512"
    echo "  md5"

    echo
    echo -e "${CYAN}Examples:${RESET}"
    echo "  hashstring sha256 \"hello world\""
    echo "      Generate a SHA-256 hash."

    echo "  hashstring verify sha256 \\"
    echo "      e59ff97941044f85df5297e1c302d260 \\"
    echo "      \"hello world\""
    echo "      Verify a SHA-256 hash."

    echo
    echo -e "${CYAN}Exit Codes:${RESET}"
    echo "  0   Success"
    echo "  1   Unsupported or invalid format"
    echo "  2   Missing or invalid arguments"
    echo "  3   Verification failed"
    echo "  4   Internal error"

    echo
    echo -e "${CYAN}Notes:${RESET}"
    echo "  hashstring is architecture-independent."
    echo "  It runs on any POSIX-compliant shell with standard hashing utilities."
}


version() {
    echo "hashstring version $VERSION"
}

list_formats() {
    echo -e "${CYAN}Supported formats:${RESET}"
    echo "  bcrypt"
    echo "  sha256"
    echo "  sha512"
    echo "  md5"
}

verify_hash() {
    format="$1"
    hash="$2"
    password="$3"

    case "$format" in
        bcrypt)
            # mkpasswd cannot verify, so use Python's bcrypt module
            python3 - <<EOF
import bcrypt
pw = b"$password"
h = b"$hash"
if bcrypt.checkpw(pw, h):
    print("MATCH")
else:
    print("NO MATCH")
EOF
            ;;

        sha256)
            calc=$(echo -n "$password" | sha256sum | awk '{print $1}')
            if [ "$calc" = "$hash" ]; then
                echo -e "${GREEN}MATCH${RESET}"
            else
                echo -e "${RED}NO MATCH${RESET}"
            fi
            ;;

        sha512)
            calc=$(echo -n "$password" | sha512sum | awk '{print $1}')
            if [ "$calc" = "$hash" ]; then
                echo -e "${GREEN}MATCH${RESET}"
            else
                echo -e "${RED}NO MATCH${RESET}"
            fi
            ;;

        md5)
            calc=$(echo -n "$password" | md5sum | awk '{print $1}')
            if [ "$calc" = "$hash" ]; then
                echo -e "${GREEN}MATCH${RESET}"
            else
                echo -e "${RED}NO MATCH${RESET}"
            fi
            ;;

        *)
            echo -e "${RED}Unknown format: $format${RESET}"
            exit 2
            ;;
    esac
}

# No args → usage
if [ $# -lt 1 ]; then
    usage
    exit 1
fi

format="$1"

case "$format" in
    --help)
        help
        exit 0
        ;;

    --version)
        version
        exit 0
        ;;

    list)
        list_formats
        exit 0
        ;;

    verify)
        if [ $# -ne 4 ]; then
            echo -e "${RED}Usage:${RESET} hashstring verify <format> <hash> <password>"
            exit 1
        fi
        verify_hash "$2" "$3" "$4"
        exit 0
        ;;
esac

# Hashing mode
password="$2"

if [ -z "$password" ]; then
    usage
    exit 1
fi

case "$format" in
    bcrypt)
        mkpasswd -m bcrypt "$password"
        ;;

    sha256)
        echo -n "$password" | sha256sum | awk '{print $1}'
        ;;

    sha512)
        echo -n "$password" | sha512sum | awk '{print $1}'
        ;;

    md5)
        echo -n "$password" | md5sum | awk '{print $1}'
        ;;

    *)
        echo -e "${RED}Unknown format: $format${RESET}"
        echo "Use: hashstring list   to see supported formats"
        exit 2
        ;;
esac
