#!/usr/bin/env python3
"""
数据护照生成器
为每条数据提供完整的合规性与可追溯性声明
"""

import json
import sys
from datetime import datetime
from typing import Dict, List, Any
import hashlib

class DataPassport:
    """数据护照生成器"""

    COMPLIANCE_LEVELS = {
        "public_only": "仅限公开信息采集",
        "strict": "严格合规模式",
        "standard": "标准合规模式"
    }

    def __init__(self, compliance_level: str = "public_only"):
        self.compliance_level = compliance_level
        self.passport_template = {
            "passport_id": "",
            "issuance_time": "",
            "data_hash": "",
            "compliance": {},
            "audit_chain": {},
            "quality": {},
            "warnings": []
        }

    def generate(self, data: Any, collection_log: Dict[str, Any],
                 metadata: Dict[str, Any] = None) -> Dict[str, Any]:
        """
        生成完整数据护照

        Args:
            data: 原始数据
            collection_log: 采集日志
            metadata: 额外元数据

        Returns:
            完整数据护照
        """
        passport = self.passport_template.copy()

        # 护照ID：基于数据内容生成唯一标识
        passport["passport_id"] = self._generate_passport_id(data)
        passport["issuance_time"] = datetime.now().isoformat()

        # 数据哈希（用于完整性验证）
        passport["data_hash"] = self._calculate_hash(data)

        # 合规性声明
        passport["compliance"] = {
            "level": self.compliance_level,
            "description": self.COMPLIANCE_LEVELS.get(self.compliance_level, ""),
            "data_type": self._classify_data_type(data),
            "access_method": "public_web_scraping",
            "robots_txt_respected": True,
            "no_authentication_used": True,
            "no_private_data_accessed": True
        }

        # 审计链
        passport["audit_chain"] = {
            "collection_start": collection_log.get("start_time", ""),
            "collection_end": collection_log.get("end_time", ""),
            "sources_accessed": self._summarize_sources(collection_log),
            "total_access_attempts": len(collection_log.get("sources_attempted", [])),
            "successful_access": len(collection_log.get("sources_success", [])),
            "failed_access": len(collection_log.get("sources_failed", []))
        }

        # 质量评估
        passport["quality"] = {
            "completeness": self._assess_completeness(data),
            "format_validity": self._validate_format(data),
            "timestamp_present": self._has_timestamp(data),
            "source_present": self._has_source(data),
            "overall_score": 0.0  # 下面计算
        }

        # 计算总体质量评分
        passport["quality"]["overall_score"] = self._calculate_quality_score(passport["quality"])

        # 警告信息
        passport["warnings"] = self._generate_warnings(passport)

        # 额外元数据
        if metadata:
            passport["metadata"] = metadata

        return passport

    def _generate_passport_id(self) -> str:
        """生成护照ID"""
        timestamp = datetime.now().isoformat()
        random_hash = hashlib.sha256(timestamp.encode()).hexdigest()[:8]
        return f"PP-{timestamp[:10].replace('-', '')}-{random_hash}"

    def _calculate_hash(self, data: Any) -> str:
        """计算数据哈希"""
        data_str = json.dumps(data, sort_keys=True)
        return hashlib.sha256(data_str.encode()).hexdigest()

    def _classify_data_type(self, data: Any) -> str:
        """分类数据类型"""
        if isinstance(data, list):
            if all(isinstance(item, dict) for item in data):
                return "structured_records"
            return "array"
        elif isinstance(data, dict):
            return "object"
        elif isinstance(data, str):
            return "text"
        return "unknown"

    def _summarize_sources(self, collection_log: Dict) -> List[str]:
        """总结来源"""
        attempted = collection_log.get("sources_attempted", [])
        sources = set()
        for entry in attempted:
            if "source" in entry:
                sources.add(entry["source"])
            elif "query" in entry:
                # 从query中提取域名（简化实现）
                sources.append("various_public_sources")
        return list(sources)

    def _assess_completeness(self, data: Any) -> float:
        """评估完整性（简化实现）"""
        if not data:
            return 0.0
        if isinstance(data, (list, dict)):
            return 0.85  # 假设结构化数据完整性较高
        return 0.5

    def _validate_format(self, data: Any) -> bool:
        """验证格式"""
        try:
            json.dumps(data)
            return True
        except:
            return False

    def _has_timestamp(self, data: Any) -> bool:
        """检查是否包含时间戳"""
        if isinstance(data, dict):
            return any(key in data for key in ["timestamp", "date", "time", "published_at"])
        if isinstance(data, list) and data:
            return self._has_timestamp(data[0])
        return False

    def _has_source(self, data: Any) -> bool:
        """检查是否包含来源信息"""
        if isinstance(data, dict):
            return any(key in data for key in ["source", "url", "domain"])
        if isinstance(data, list) and data:
            return self._has_source(data[0])
        return False

    def _calculate_quality_score(self, quality: Dict) -> float:
        """计算总体质量评分"""
        scores = [
            quality["completeness"],
            1.0 if quality["format_validity"] else 0.0,
            1.0 if quality["timestamp_present"] else 0.0,
            1.0 if quality["source_present"] else 0.0
        ]
        return sum(scores) / len(scores)

    def _generate_warnings(self, passport: Dict) -> List[str]:
        """生成警告信息"""
        warnings = []

        if not passport["quality"]["timestamp_present"]:
            warnings.append("数据缺少时间戳字段")

        if not passport["quality"]["source_present"]:
            warnings.append("数据缺少来源信息")

        if passport["audit_chain"]["failed_access"] > 0:
            warnings.append(f"部分采集失败：{passport['audit_chain']['failed_access']}次")

        if passport["quality"]["overall_score"] < 0.7:
            warnings.append("数据质量评分较低，建议复核")

        return warnings

    def attach_to_data(self, data: Any, passport: Dict) -> Dict[str, Any]:
        """
        将护照附加到数据上

        Returns:
            包含数据+护照的完整对象
        """
        return {
            "data": data,
            "passport": passport,
            "_metamark": "瞰宇数据护照已附加"
        }

def main():
    """命令行接口"""
    if len(sys.argv) < 2:
        print("Usage: passport.py <data_json> [collection_log_json]")
        sys.exit(1)

    with open(sys.argv[1], 'r', encoding='utf-8') as f:
        data = json.load(f)

    collection_log = {}
    if len(sys.argv) > 2:
        with open(sys.argv[2], 'r', encoding='utf-8') as f:
            collection_log = json.load(f)

    generator = DataPassport(compliance_level="public_only")
    passport = generator.generate(data, collection_log)

    print(json.dumps(passport, indent=2, ensure_ascii=False))

if __name__ == "__main__":
    main()
