/**
 * Pacifica签名器契约测试
 *
 * 验证IPacificaSigner接口的契约实现
 * 测试Ed25519签名、批量操作、消息序列化等Pacifica特定功能
 */

import { describe, test, expect, beforeEach, afterEach } from '@jest/globals';
import {
  PacificaSigner,
  PacificaSignRequest,
  PacificaSignResponse,
  PacificaVerifyRequest,
  PacificaOrderType,
  PacificaOrderMessage,
  PacificaCancelMessage,
  PACIFICA_CONSTANTS,
  Platform,
  SignResult
} from '../../src/index';

describe('IPacificaSigner Contract Tests', () => {
  let signer: PacificaSigner;
  const testAccountId = 'pacifica-signer-test-001';

  beforeEach(async () => {
    // 创建PacificaSigner实例并添加测试账户
    const { PacificaSigner } = await import('../../src/platforms/pacifica/PacificaSigner');
    signer = new PacificaSigner();

    // 添加测试账户私钥（64字符十六进制）
    const testPrivateKey = '1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef';
    signer.addAccount(testAccountId, testPrivateKey);
  });

  afterEach(async () => {
    // 清理资源
  });

  describe('平台接口验证', () => {
    test('应该正确标识Pacifica平台', () => {
      expect(signer.platform).toBe(Platform.PACIFICA);
    });
  });

  describe('Ed25519签名功能', () => {
    test('应该能对Pacifica订单进行签名', async () => {
      const orderMessage: PacificaOrderMessage = {
        order_type: PacificaOrderType.LIMIT,
        symbol: 'BTC-USD',
        side: 'buy',
        size: '0.001',
        price: '65000.00',
        client_id: 'test-order-001',
        timestamp: Date.now(),
        expiry: Date.now() + 300000
      };

      const messageBytes = new TextEncoder().encode(JSON.stringify(orderMessage));

      const request: PacificaSignRequest = {
        accountId: testAccountId,
        message: messageBytes,
        orderType: PacificaOrderType.LIMIT,
        options: {
          timeout: 30000,
          includeTimestamp: true,
          encoding: 'base64'
        }
      };

      const response = await signer.signOrder(request);

      expect(response.success).toBe(true);
      expect(response.signature).toBeDefined();
      expect(response.signature.length).toBe(PACIFICA_CONSTANTS.SIGNATURE_BASE64_LENGTH);
      expect(response.algorithm).toBe('ed25519');
      expect(response.publicKey).toBeDefined();
      expect(response.publicKey.length).toBe(PACIFICA_CONSTANTS.PUBLIC_KEY_BASE58_LENGTH);
      expect(response.orderType).toBe(PacificaOrderType.LIMIT);
      expect(response.timestamp).toBeInstanceOf(Date);
      expect(response.executionTime).toBeLessThan(50); // NFR-002: <50ms
    });

    test('应该能对市价单进行签名', async () => {
      const orderMessage: PacificaOrderMessage = {
        order_type: PacificaOrderType.MARKET,
        symbol: 'ETH-USD',
        side: 'sell',
        size: '0.1',
        client_id: 'market-order-001',
        timestamp: Date.now()
      };

      const messageBytes = new TextEncoder().encode(JSON.stringify(orderMessage));

      const request: PacificaSignRequest = {
        accountId: testAccountId,
        message: messageBytes,
        orderType: PacificaOrderType.MARKET
      };

      const response = await signer.signOrder(request);

      expect(response.success).toBe(true);
      expect(response.algorithm).toBe('ed25519');
      expect(response.orderType).toBe(PacificaOrderType.MARKET);
    });

    test('应该能对取消订单进行签名', async () => {
      const cancelMessage: PacificaCancelMessage = {
        action: 'cancel',
        order_type: 'cancel',
        order_id: 'order-to-cancel-123',
        timestamp: Date.now()
      };

      const messageBytes = new TextEncoder().encode(JSON.stringify(cancelMessage));

      const request: PacificaSignRequest = {
        accountId: testAccountId,
        message: messageBytes,
        orderType: PacificaOrderType.CANCEL
      };

      const response = await signer.signOrder(request);

      expect(response.success).toBe(true);
      expect(response.orderType).toBe(PacificaOrderType.CANCEL);
    });
  });

  describe('签名验证功能', () => {
    test('应该能验证有效的Ed25519签名', async () => {
      // 首先创建一个签名
      const orderMessage: PacificaOrderMessage = {
        order_type: PacificaOrderType.LIMIT,
        symbol: 'BTC-USD',
        side: 'buy',
        size: '0.001',
        price: '65000.00',
        client_id: 'verify-test-001',
        timestamp: Date.now()
      };

      const messageBytes = new TextEncoder().encode(JSON.stringify(orderMessage));

      const signResponse = await signer.signOrder({
        accountId: testAccountId,
        message: messageBytes,
        orderType: PacificaOrderType.LIMIT
      });

      expect(signResponse.success).toBe(true);

      // 然后验证签名
      const verifyRequest: PacificaVerifyRequest = {
        accountId: testAccountId,
        message: messageBytes,
        signature: signResponse.signature,
        publicKey: signResponse.publicKey,
        orderType: PacificaOrderType.LIMIT
      };

      const verifyResponse = await signer.verifySignature(verifyRequest);

      expect(verifyResponse.success).toBe(true);
      expect(verifyResponse.isValid).toBe(true);
      expect(verifyResponse.algorithm).toBe('ed25519');
      expect(verifyResponse.publicKey).toBe(signResponse.publicKey);
      expect(verifyResponse.timestamp).toBeInstanceOf(Date);
      expect(verifyResponse.verificationId).toBeDefined();
    });

    test('应该拒绝被篡改的消息签名', async () => {
      // 创建原始签名
      const originalMessage = new TextEncoder().encode('original message');
      const signResponse = await signer.signOrder({
        accountId: testAccountId,
        message: originalMessage,
        orderType: PacificaOrderType.MARKET
      });

      // 尝试验证不同的消息（篡改）
      const tamperedMessage = new TextEncoder().encode('tampered message');
      const verifyRequest: PacificaVerifyRequest = {
        accountId: testAccountId,
        message: tamperedMessage,
        signature: signResponse.signature,
        publicKey: signResponse.publicKey
      };

      const verifyResponse = await signer.verifySignature(verifyRequest);

      expect(verifyResponse.success).toBe(true); // 验证操作成功
      expect(verifyResponse.isValid).toBe(false); // 但签名无效
    });

    test('应该拒绝无效格式的签名', async () => {
      const message = new TextEncoder().encode('test message');
      const verifyRequest: PacificaVerifyRequest = {
        accountId: testAccountId,
        message: message,
        signature: 'invalid-signature-format',
        publicKey: 'valid-looking-public-key-base58'
      };

      const verifyResponse = await signer.verifySignature(verifyRequest);

      expect(verifyResponse.success).toBe(false);
      expect(verifyResponse.error).toBeDefined();
      expect(verifyResponse.error).toContain('INVALID');
    });
  });

  describe('公钥管理', () => {
    test('应该能获取账户公钥', async () => {
      const publicKey = await signer.getPublicKey(testAccountId);

      expect(publicKey).toBeDefined();
      expect(typeof publicKey).toBe('string');
      expect(publicKey.length).toBe(PACIFICA_CONSTANTS.PUBLIC_KEY_BASE58_LENGTH);

      // 验证Base58格式（基本检查）
      expect(/^[1-9A-HJ-NP-Za-km-z]+$/.test(publicKey)).toBe(true);
    });

    test('应该为不存在的账户返回错误', async () => {
      await expect(signer.getPublicKey('non-existent-account'))
        .rejects.toThrow('ACCOUNT_NOT_FOUND');
    });
  });

  describe('批量签名功能', () => {
    test('应该能执行批量签名操作', async () => {
      const orders: PacificaOrderMessage[] = [
        {
          order_type: PacificaOrderType.LIMIT,
          symbol: 'BTC-USD',
          side: 'buy',
          size: '0.001',
          price: '65000.00',
          client_id: 'batch-order-1',
          timestamp: Date.now()
        },
        {
          order_type: PacificaOrderType.MARKET,
          symbol: 'ETH-USD',
          side: 'sell',
          size: '0.1',
          client_id: 'batch-order-2',
          timestamp: Date.now()
        },
        {
          action: 'cancel',
          order_type: PacificaOrderType.CANCEL,
          order_id: 'order-to-cancel',
          timestamp: Date.now(),
          side: 'buy', // Add required fields for compatibility
          size: '0'
        } as any
      ];

      const requests: PacificaSignRequest[] = orders.map((order, index) => ({
        accountId: testAccountId,
        message: new TextEncoder().encode(JSON.stringify(order)),
        orderType: order.order_type as PacificaOrderType
      }));

      const startTime = Date.now();
      const responses = await signer.signBatch(requests);
      const totalTime = Date.now() - startTime;

      expect(responses).toHaveLength(requests.length);
      expect(totalTime).toBeLessThan(300); // 批量操作应该在300ms内完成

      responses.forEach((response, index) => {
        expect(response.success).toBe(true);
        expect(response.signature).toBeDefined();
        expect(response.algorithm).toBe('ed25519');
        expect(response.orderType).toBe(orders[index]?.order_type);
        expect(response.executionTime).toBeLessThan(50);
      });

      // 验证所有签名都是唯一的
      const signatures = responses.map(r => r.signature);
      const uniqueSignatures = new Set(signatures);
      expect(uniqueSignatures.size).toBe(signatures.length);
    });

    test('应该拒绝超过最大批量大小的请求', async () => {
      const requests: PacificaSignRequest[] = Array.from(
        { length: PACIFICA_CONSTANTS.MAX_BATCH_SIZE + 1 },
        (_, index) => ({
          accountId: testAccountId,
          message: new TextEncoder().encode(`batch message ${index}`),
          orderType: PacificaOrderType.MARKET
        })
      );

      await expect(signer.signBatch(requests))
        .rejects.toThrow('BATCH_SIZE_EXCEEDED');
    });

    test('应该处理批量请求中的部分失败', async () => {
      const requests: PacificaSignRequest[] = [
        {
          accountId: testAccountId,
          message: new TextEncoder().encode('valid message 1'),
          orderType: PacificaOrderType.LIMIT
        },
        {
          accountId: 'invalid-account',
          message: new TextEncoder().encode('valid message 2'),
          orderType: PacificaOrderType.MARKET
        },
        {
          accountId: testAccountId,
          message: new TextEncoder().encode('valid message 3'),
          orderType: PacificaOrderType.CANCEL
        }
      ];

      const responses = await signer.signBatch(requests);

      expect(responses).toHaveLength(3);
      expect(responses[0]?.success).toBe(true);
      expect(responses[1]?.success).toBe(false);
      expect(responses[1]?.error).toContain('ACCOUNT_NOT_FOUND');
      expect(responses[2]?.success).toBe(true);
    });
  });

  describe('签名选项和编码', () => {
    test('应该支持不同的签名编码格式', async () => {
      const message = new TextEncoder().encode('encoding test message');
      const encodings: Array<'base64' | 'base58' | 'hex'> = ['base64', 'base58', 'hex'];

      for (const encoding of encodings) {
        const request: PacificaSignRequest = {
          accountId: testAccountId,
          message: message,
          orderType: PacificaOrderType.MARKET,
          options: { encoding }
        };

        const response = await signer.signOrder(request);

        expect(response.success).toBe(true);
        expect(response.signature).toBeDefined();

        // 验证编码格式
        switch (encoding) {
          case 'base64':
            expect(/^[A-Za-z0-9+/]+=*$/.test(response.signature)).toBe(true);
            break;
          case 'base58':
            expect(/^[1-9A-HJ-NP-Za-km-z]+$/.test(response.signature)).toBe(true);
            break;
          case 'hex':
            expect(/^[0-9a-fA-F]+$/.test(response.signature)).toBe(true);
            break;
        }
      }
    });

    test('应该支持时间戳包含选项', async () => {
      const message = new TextEncoder().encode('timestamp test message');

      // 包含时间戳
      const withTimestamp = await signer.signOrder({
        accountId: testAccountId,
        message: message,
        orderType: PacificaOrderType.LIMIT,
        options: { includeTimestamp: true }
      });

      // 不包含时间戳
      const withoutTimestamp = await signer.signOrder({
        accountId: testAccountId,
        message: message,
        orderType: PacificaOrderType.LIMIT,
        options: { includeTimestamp: false }
      });

      expect(withTimestamp.success).toBe(true);
      expect(withoutTimestamp.success).toBe(true);

      // 签名应该不同（因为时间戳的存在）
      expect(withTimestamp.signature).not.toBe(withoutTimestamp.signature);
    });

    test('应该遵守签名超时设置', async () => {
      const message = new TextEncoder().encode('timeout test message');

      // 极短超时应该失败
      const shortTimeoutRequest: PacificaSignRequest = {
        accountId: testAccountId,
        message: message,
        orderType: PacificaOrderType.MARKET,
        options: { timeout: 1 } // 1ms
      };

      const response = await signer.signOrder(shortTimeoutRequest);

      expect(response.success).toBe(false);
      expect(response.error).toContain('TIMEOUT');
    });
  });

  describe('消息大小限制', () => {
    test('应该拒绝过大的消息', async () => {
      // 创建超过最大大小的消息
      const largeMessage = new Uint8Array(PACIFICA_CONSTANTS.MAX_MESSAGE_SIZE + 1);
      largeMessage.fill(65); // 填充'A'字符

      const request: PacificaSignRequest = {
        accountId: testAccountId,
        message: largeMessage,
        orderType: PacificaOrderType.MARKET
      };

      const response = await signer.signOrder(request);

      expect(response.success).toBe(false);
      expect(response.error).toContain('MESSAGE_TOO_LARGE');
    });

    test('应该接受最大大小以内的消息', async () => {
      // 创建恰好最大大小的消息
      const maxSizeMessage = new Uint8Array(PACIFICA_CONSTANTS.MAX_MESSAGE_SIZE);
      maxSizeMessage.fill(65);

      const request: PacificaSignRequest = {
        accountId: testAccountId,
        message: maxSizeMessage,
        orderType: PacificaOrderType.MARKET
      };

      const response = await signer.signOrder(request);

      expect(response.success).toBe(true);
      expect(response.signature).toBeDefined();
    });
  });

  describe('错误处理和边界条件', () => {
    test('应该处理空消息', async () => {
      const emptyMessage = new Uint8Array(0);

      const request: PacificaSignRequest = {
        accountId: testAccountId,
        message: emptyMessage,
        orderType: PacificaOrderType.MARKET
      };

      const response = await signer.signOrder(request);

      expect(response.success).toBe(false);
      expect(response.error).toContain('INVALID_MESSAGE');
    });

    test('应该处理无效的订单类型', async () => {
      const message = new TextEncoder().encode('test message');

      const request: PacificaSignRequest = {
        accountId: testAccountId,
        message: message,
        orderType: 'invalid_order_type' as any
      };

      const response = await signer.signOrder(request);

      expect(response.success).toBe(false);
      expect(response.error).toContain('INVALID_ORDER_TYPE');
    });

    test('应该在并发场景下保持稳定', async () => {
      const message = new TextEncoder().encode('concurrent test message');
      const concurrentRequests = 20;

      const promises = Array.from({ length: concurrentRequests }, (_, index) =>
        signer.signOrder({
          accountId: testAccountId,
          message: message,
          orderType: PacificaOrderType.MARKET
        })
      );

      const results = await Promise.all(promises);

      results.forEach((result, index) => {
        expect(result.success).toBe(true);
        expect(result.signature).toBeDefined();
        expect(result.executionTime).toBeLessThan(50);
      });

      // 验证所有签名都是唯一的
      const signatures = results.map(r => r.signature);
      const uniqueSignatures = new Set(signatures);
      expect(uniqueSignatures.size).toBe(signatures.length);
    });
  });
});