#!/usr/bin/env python3
import json
import datetime
import argparse
import sys
import hashlib

# ── Aegis Trust CLI Ingestion Probe ──
# Performs local read-only checks on S3 public blocks and IAM user MFA status.
# Outputs aegis-audit-log.json for secure zero-trust portal ingestion.

def calculate_checksum(data):
    # Calculates a secure SHA-256 integrity signature of the findings content
    raw_str = json.dumps(data, sort_keys=True)
    return hashlib.sha256(raw_str.encode('utf-8')).hexdigest()

def generate_offline_demo(account_id, bucket_name, username, output_file):
    findings = {
        "s3_buckets": [
            {
                "name": bucket_name or "aegis-demo-assets-bucket",
                "public_block_active": False
            }
        ],
        "iam_mfa": [
            {
                "username": username or "deploy-admin-cli",
                "mfa_active": False
            }
        ]
    }
    
    timestamp = datetime.datetime.now(datetime.timezone.utc).strftime('%Y-%m-%d %H:%M:%S UTC')
    
    report = {
        "schema_version": "aegis-v1",
        "timestamp": timestamp,
        "aws_account_id": account_id or "999999999999",
        "findings": findings
    }
    
    report["integrity_signature"] = calculate_checksum(report["findings"])
    
    with open(output_file, 'w') as f:
        json.dump(report, f, indent=2)
    
    print(f"\n[OK] Offline mock audit report successfully generated: {output_file}")
    print(f"You can now upload this file to the Aegis Trust Secure Drop Ingestion drawer to view the scan.")

def main():
    parser = argparse.ArgumentParser(description="Aegis Trust local compliance scanning probe.")
    parser.add_argument("--profile", help="AWS CLI credential profile name", default=None)
    parser.add_argument("--region", help="AWS region name", default="us-east-1")
    parser.add_argument("--output", help="Output file path", default="aegis-audit-log.json")
    parser.add_argument("--offline-demo", action="store_true", help="Generate an offline demo log file without contacting AWS")
    parser.add_argument("--demo-account", help="Mock account ID for offline demo", default="999999999999")
    parser.add_argument("--demo-bucket", help="Mock bucket name for offline demo", default="aegis-demo-assets-bucket")
    parser.add_argument("--demo-user", help="Mock username for offline demo", default="deploy-admin-cli")
    
    args = parser.parse_args()

    if args.offline_demo:
        generate_offline_demo(args.demo_account, args.demo_bucket, args.demo_user, args.output)
        sys.exit(0)

    try:
        import boto3
        from botocore.exceptions import NoCredentialsError, PartialCredentialsError
    except ImportError:
        print("\n[!] Error: 'boto3' library is not installed.")
        print("Please install it running: pip install boto3")
        print("\nTo generate a sample mock audit log for local sandbox testing, run:")
        print(f"python aeg-probe.py --offline-demo --output {args.output}")
        sys.exit(1)

    print(f"Initializing Aegis Ingestion Probe on region: {args.region}...")

    try:
        session = boto3.Session(profile_name=args.profile, region_name=args.region)
        sts = session.client('sts')
        identity = sts.get_caller_identity()
        aws_account_id = identity['Account']
        print(f"Caller Identity Verified (AWS Account: {aws_account_id})")
        
        s3 = session.client('s3')
        iam = session.client('iam')
        
    except (NoCredentialsError, PartialCredentialsError):
        print("\n[!] Error: AWS credentials not found or incomplete.")
        print("Please configure your credentials using 'aws configure' or environment variables.")
        print("\nTo generate a sample mock audit log for local sandbox testing, run:")
        print(f"python aeg-probe.py --offline-demo --output {args.output}")
        sys.exit(1)
    except Exception as e:
        print(f"\n[!] Connection error: {e}")
        sys.exit(1)

    # 1. Scan S3 Buckets
    print("Auditing S3 Storage buckets...")
    s3_findings = []
    try:
        buckets = s3.list_buckets().get('Buckets', [])
        for b in buckets:
            name = b['Name']
            public_blocked = True
            try:
                block = s3.get_public_access_block(Bucket=name)
                config = block.get('PublicAccessBlockConfiguration', {})
                # If any of these are False, public access block is disabled/deficient
                if not all([config.get('BlockPublicAcls', False),
                            config.get('BlockPublicPolicy', False),
                            config.get('IgnorePublicAcls', False),
                            config.get('RestrictPublicBuckets', False)]):
                    public_blocked = False
            except Exception:
                # If get_public_access_block throws, it usually means no block is configured (hence public)
                public_blocked = False
                
            s3_findings.append({
                "name": name,
                "public_block_active": public_blocked
            })
    except Exception as e:
        print(f"S3 audit warning: {e}")

    # 2. Scan IAM MFA
    print("Auditing IAM Identities...")
    iam_findings = []
    try:
        users = iam.list_users().get('Users', [])
        for u in users:
            username = u['UserName']
            mfa_devices = iam.list_mfa_devices(UserName=username).get('MFADevices', [])
            iam_findings.append({
                "username": username,
                "mfa_active": len(mfa_devices) > 0
            })
    except Exception as e:
        print(f"IAM audit warning: {e}")

    # 3. Compile report
    findings = {
        "s3_buckets": s3_findings,
        "iam_mfa": iam_findings
    }
    
    timestamp = datetime.datetime.now(datetime.timezone.utc).strftime('%Y-%m-%d %H:%M:%S UTC')
    
    report = {
        "schema_version": "aegis-v1",
        "timestamp": timestamp,
        "aws_account_id": aws_account_id,
        "findings": findings
    }
    
    report["integrity_signature"] = calculate_checksum(report["findings"])

    with open(args.output, 'w') as f:
        json.dump(report, f, indent=2)

    print(f"\n[OK] Scan completed successfully. Report saved to: {args.output}")
    print("Ingestion file is ready. Upload this file to the Aegis Trust Secure Drop portal to view active compliance gaps.")

if __name__ == "__main__":
    main()
