import crypto from 'crypto';
import db from '../../config/database';
import { logger } from '../../utils/logger';

export interface NodeIdentity {
  nodeId: string;
  hardwareFingerprint: string;
  clientCertFingerprint?: string; // [CORE_SEC_07] mTLS 证书指纹
  publicKey: string;
  status: 'PENDING' | 'TRUSTED' | 'REVOKED';
  lastSeenAt: Date;
}

/**
 * [CORE_SEC_04] 零信任节点身份管理服务
 * @description 结合硬件指纹与非对称加密，确保只有受信任的物理设备能接入 Hub
 */
export class NodeIdentityService {
  private static readonly TABLE_NAME = 'cf_node_identities';

  /**
   * 注册/更新节点身份 (基于硬件指纹与 mTLS 证书)
   */
  static async registerNode(params: {
    nodeId: string;
    hardwareFingerprint: string;
    clientCertFingerprint?: string;
    publicKey: string;
  }): Promise<boolean> {
    const { nodeId, hardwareFingerprint, clientCertFingerprint, publicKey } = params;

    const existing = await db(this.TABLE_NAME).where({ node_id: nodeId }).first();

    if (existing) {
      // 零信任校验：如果硬件指纹或证书指纹不匹配，拒绝更新
      if (existing.hardware_fingerprint !== hardwareFingerprint) {
        logger.error(`[ZeroTrust] Node ID ${nodeId} hardware fingerprint mismatch!`);
        return false;
      }

      if (clientCertFingerprint && existing.client_cert_fingerprint && existing.client_cert_fingerprint !== clientCertFingerprint) {
        logger.error(`[ZeroTrust] Node ID ${nodeId} mTLS certificate mismatch! Potential spoofing.`);
        return false;
      }

      await db(this.TABLE_NAME).where({ node_id: nodeId }).update({
        public_key: publicKey,
        client_cert_fingerprint: clientCertFingerprint || existing.client_cert_fingerprint,
        last_seen_at: new Date(),
        updated_at: new Date()
      });
    } else {
      await db(this.TABLE_NAME).insert({
        node_id: nodeId,
        hardware_fingerprint: hardwareFingerprint,
        client_cert_fingerprint: clientCertFingerprint,
        public_key: publicKey,
        status: 'PENDING',
        last_seen_at: new Date(),
        created_at: new Date(),
        updated_at: new Date()
      });
      logger.info(`[ZeroTrust] New node registered: ${nodeId} (mTLS: ${!!clientCertFingerprint})`);
    }

    return true;
  }

  /**
   * 验证节点签名的请求负载 (Challenge-Response)
   */
  static async verifyNodeSignature(nodeId: string, payload: any, signature: string): Promise<boolean> {
    const node = await db(this.TABLE_NAME).where({ node_id: nodeId, status: 'TRUSTED' }).first();
    if (!node) return false;

    try {
      const verifier = crypto.createVerify('SHA256');
      verifier.update(JSON.stringify(payload));
      return verifier.verify(node.public_key, signature, 'base64');
    } catch (err) {
      return false;
    }
  }

  /**
   * 初始化数据库表
   */
  static async initTable() {
    const exists = await db.schema.hasTable(this.TABLE_NAME);
    if (!exists) {
      logger.info(`📦 Creating ${this.TABLE_NAME} table...`);
      await db.schema.createTable(this.TABLE_NAME, (table) => {
        table.string('node_id', 64).primary();
        table.string('hardware_fingerprint', 128).notNullable();
        table.string('client_cert_fingerprint', 128);
        table.text('public_key').notNullable();
        table.string('status', 16).defaultTo('PENDING');
        table.timestamp('last_seen_at');
        table.timestamps(true, true);

        table.index(['hardware_fingerprint']);
      });
      logger.info(`✅ Table ${this.TABLE_NAME} created`);
    }
  }
}
