#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
P0 v0.2 后端白名单 · 真功能验证
================================
不从「我以为的白名单」验证，而是从【落盘后的生产文件】把 _clean_block / _block_empty
源码抽出来 exec，再用真实输入跑。这样才能证明销售填的数据真能活下来。

关键断言：只填 P0 新字段的块，必须【不被判空丢弃】且【字段值原样保留】。
"""
import io
import os
import re
import sys
import textwrap

SRC = os.path.expanduser('~/Desktop/Hermes输出-工作类/脚本/销售工作台服务.py')
s = io.open(SRC, encoding='utf-8').read()

# ── 抽取 _clean_block + _block_empty 源码 ──
i = s.index('def _clean_block(b):')
i = s.rindex('\n', 0, i) + 1   # 回退到行首：否则首行是「行中间切出来的」，缩进算成 0
j = s.index('blocks = [_clean_block(b) for b in raw_blocks]')
chunk = s[i:j]
# 按【最小缩进】精确剥离。
# 注意：不能用 chunk[0] 的前导空格算缩进 —— s.index('def _clean_block(b):') 返回的是
# 子串起始位置（即 'd'），不含前导空格，算出来 _ind=0，剥离后函数体缩进全错。
_ind = min(len(l) - len(l.lstrip(' ')) for l in chunk.split('\n') if l.strip())
chunk = '\n'.join((l[_ind:] if l.strip() else '') for l in chunk.split('\n'))
print('  · 抽取缩进 = %d 空格，共 %d 行' % (_ind, len(chunk.split('\n'))))
ns = {}
exec(compile(chunk, 'extracted', 'exec'), ns)
_clean_block = ns['_clean_block']
_block_empty = ns['_block_empty']
print('  ✅ 已从生产文件抽出 _clean_block / _block_empty 并 exec 成功')

fails = []


def check(name, cond, detail=''):
    if cond:
        print('  ✅ %s' % name)
    else:
        print('  ❌ %s  %s' % (name, detail))
        fails.append(name)


print('\n=== A. 只填 P0 新字段的块（v0.2 的核心修复点）===')
blk = _clean_block({
    'corp_nature': '动保',
    'biz_type': '生产型',
    'founded_year': '2015',
    'headcount_scale': '100~300人',
    'strategy_focus': ['宠物', '科研高校'],
    'pain_import_cost': '进口原料涨价 30%',
    'breakthrough': '已送样 2 家',
})
check('非空判定 → 保留', not _block_empty(blk),
      '（修复前这里会被判空丢弃！）')
check('corp_nature 原样保留', blk.get('corp_nature') == '动保', repr(blk.get('corp_nature')))
check('biz_type 原样保留', blk.get('biz_type') == '生产型', repr(blk.get('biz_type')))
check('strategy_focus 数组保留', blk.get('strategy_focus') == ['宠物', '科研高校'],
      repr(blk.get('strategy_focus')))
check('founded_year 保留', blk.get('founded_year') == '2015')
check('breakthrough 保留', blk.get('breakthrough') == '已送样 2 家')

print('\n=== B. decision[] 新增 5 子字段 ===')
blk2 = _clean_block({
    'decision': [{'name': '张三', 'title': '研发总监',
                  'influence_tier': '技术把关', 'reports_to': '李总',
                  'attitude': '支持', 'comm_pref': '微信', 'focus_point': '数据完整性'}],
})
d = (blk2.get('decision') or [{}])[0]
check('decision 非空判定 → 保留', not _block_empty(blk2))
check('influence_tier 保留', d.get('influence_tier') == '技术把关', repr(d.get('influence_tier')))
check('reports_to 保留', d.get('reports_to') == '李总')
check('attitude 保留', d.get('attitude') == '支持')
check('comm_pref 保留', d.get('comm_pref') == '微信')
check('focus_point 保留', d.get('focus_point') == '数据完整性')

print('\n=== C. 空块必须丢（不能因为加了字段就啥都留）===')
check('全空块 → 判空', _block_empty(_clean_block({})))
check('只有空白字符 → 判空', _block_empty(_clean_block({'corp_nature': '   ', 'opportunity': ''})))
check('strategy_focus 空数组 → 判空', _block_empty(_clean_block({'strategy_focus': []})))

print('\n=== D. 老字段不受影响（回归）===')
blk3 = _clean_block({'need': '需要 GAPDH 引物', 'visit_goal': '确认 Q4 备货'})
check('老字段 need 保留', blk3.get('need') == '需要 GAPDH 引物')
check('老字段 visit_goal 保留', blk3.get('visit_goal') == '确认 Q4 备货')
check('老字段块 → 保留', not _block_empty(blk3))

print('\n=== E. 白名单覆盖面核对 ===')
for k in ['founded_year', 'registered_capital_wan', 'financing_status', 'headcount_scale',
          'corp_nature', 'biz_type', 'strategy_focus', 'license_status', 'license_count',
          'registering_products', 'risk_notes', 'risk_note_source', 'price_priority',
          'require_backup_vendor', 'vendor_decider', 'negotiation_rounds', 'quote_buffer',
          'phase_split_reg_opt', 'pain_labor_shortage', 'pain_import_cost', 'pain_notes',
          'segment', 'product_line', 'annual_volume_t', 'volume_unit', 'reaction_system',
          'incumbent_brand', 'test_ref', 'opportunity', 'challenge', 'support_needed',
          'breakthrough']:
    probe = _clean_block({k: (['x'] if k == 'strategy_focus' else 'X')})
    if probe.get(k) != (['x'] if k == 'strategy_focus' else 'X'):
        fails.append('白名单缺 ' + k)
        print('  ❌ 白名单缺 %s' % k)
print('  ✅ 32 个块级新 key 全部在白名单内' if not any('白名单缺' in f for f in fails) else '')

print('\n' + '=' * 56)
if fails:
    print('❌ 失败 %d 项：%s' % (len(fails), fails))
    sys.exit(1)
print('✅ 全部通过 —— P0 v0.2 后端改造真功能验证 OK')
