#!/usr/bin/env python3
import sys
import random

def ip_to_int(ip: str) -> int:
    """IPBIG Convert IPv4 address to 32-bit integer"""
    try:
        a, b, c, d = map(int, ip.strip().split('.'))
        if not (0 <= a <= 255 and 0 <= b <= 255 and 0 <= c <= 255 and 0 <= d <= 255):
            raise ValueError
        return (a << 24) | (b << 16) | (c << 8) | d
    except Exception:
        raise ValueError("Invalid IPv4 address")


def int_to_ip(n: int) -> str:
    """Convert 32-bit integer back to IPv4"""
    n = n & 0xFFFFFFFF
    return f"{(n >> 24) & 0xFF}.{(n >> 16) & 0xFF}.{(n >> 8) & 0xFF}.{n & 0xFF}"


def generate_large(ip: str, target_digits: int):
    """Generate a large decimal number that works correctly with UNIX/Linux ping"""
    val = ip_to_int(ip)
    small_str = str(val)
    k = len(small_str)

    if target_digits <= k:
        return small_str, small_str

    # Calculate how many zeros we need to insert to preserve modulo 2^32
    p = 32 - k                     # number of zeros required
    random_count = target_digits - k - p

    if random_count < 1:
        # Not enough space for zeros + at least one random digit
        return small_str, small_str

    # Build the large number:
    # [random digits (first ≠ 0)] + [p zeros] + [exact small IP decimal]
    result = str(random.randint(1, 9))                    # first digit 1-9
    for _ in range(random_count - 1):
        result += str(random.randint(0, 9))

    result += '0' * p                                     # insert required zeros
    result += small_str                                   # append exact IP value

    return small_str, result


def main():
    if len(sys.argv) < 2:
        print("Usage:")
        print("  ipbig <IPv4>                  → small decimal (safe for ping)")
        print("  ipbig -s <digits> <IPv4>      → large decimal that works on UNIX/Linux")
        print("\nExamples:")
        print("  ipbig 192.168.11.1")
        print("  ipbig -s 100 192.168.11.1")
        return

    if sys.argv[1] == "-s" and len(sys.argv) == 4:
        try:
            digits = int(sys.argv[2])
            ip = sys.argv[3]
            if digits < 1 or digits > 2000:
                print("Error: digits must be between 1 and 2000")
                return

            small, large = generate_large(ip, digits)
            print(f"Small (safe for ping): {small}")
            print(f"Large (~{digits} digits): {large}")
            print("\nYou can now safely use the large number with ping on UNIX/Linux.")
        except ValueError as e:
            print(f"Error: {e}")
    else:
        # Normal mode: IP → small decimal or big → IP
        input_str = sys.argv[1]
        if '.' in input_str:
            try:
                small = str(ip_to_int(input_str))
                print(small)
            except ValueError:
                print("Error: Invalid IPv4 address")
        else:
            # Big number → IPv4
            try:
                mod = 0
                for char in input_str:
                    if char.isdigit():
                        mod = (mod * 10 + int(char)) & 0xFFFFFFFF
                print(int_to_ip(mod))
            except Exception:
                print("Error: Invalid input")


if __name__ == "__main__":
    main()
