import os
import json
import sys
import glob

def import_peer(file, data_key, name, clients_dir, meta_dir,
                groups_dir, blocks_dir, force):
    """
    Import a single peer from an export bundle.
    data_key: 'data' for peer export, 'peers' for full backup
    Returns: list of imported items as strings
    """
    import base64, os
 
    d = json.load(open(file))
 
    if data_key == 'data':
        peer = d['data']
    else:
        # Find peer in full backup peers array
        peers = d['data'].get('peers', [])
        peer = next((p for p in peers if p['name'] == name), None)
        if not peer:
            print(f"error: peer '{name}' not found in backup", file=sys.stderr)
            sys.exit(1)
 
    imported = []
 
    # conf
    conf_path = os.path.join(clients_dir, f"{name}.conf")
    if os.path.exists(conf_path) and force != 'true':
        print(f"error: peer '{name}' already exists, use --force to overwrite",
              file=sys.stderr)
        sys.exit(1)
    os.makedirs(clients_dir, exist_ok=True)
    conf = base64.b64decode(peer['conf']).decode()
    open(conf_path, 'w').write(conf)
    imported.append('conf')
 
    # meta
    meta = peer.get('meta', {})
    if meta:
        os.makedirs(meta_dir, exist_ok=True)
        open(os.path.join(meta_dir, f"{name}.meta"), 'w').write(
            json.dumps(meta, indent=2))
        imported.append('meta')
 
    # groups
    for grp in peer.get('groups', []):
        grp_file = os.path.join(groups_dir, f"{grp}.group")
        if os.path.exists(grp_file):
            try:
                g = json.load(open(grp_file))
                if name not in g.get('peers', []):
                    g.setdefault('peers', []).append(name)
                    open(grp_file, 'w').write(json.dumps(g, indent=2))
                    imported.append(f"group:{grp}")
            except Exception:
                pass
 
    # blocks
    blocks = peer.get('blocks', {})
    if blocks.get('is_blocked') and blocks.get('block_file'):
        os.makedirs(blocks_dir, exist_ok=True)
        block_data = base64.b64decode(blocks['block_file'])
        open(os.path.join(blocks_dir, f"{name}.block"), 'wb').write(block_data)
        imported.append('block')
 
    print('\n'.join(imported))
 
 
def import_identity(file, name, identities_dir, clients_dir, force):
    """Import an identity from an export bundle."""
    import os
 
    d = json.load(open(file))
    id_data = d['data'].get('identity', d['data'])
 
    # Check all referenced peers exist
    peers = id_data.get('peers', [])
    missing = [p for p in peers
               if not os.path.exists(os.path.join(clients_dir, f"{p}.conf"))]
    if missing:
        print(f"error: missing peers: {' '.join(missing)}", file=sys.stderr)
        sys.exit(1)
 
    id_file = os.path.join(identities_dir, f"{name}.identity")
    if os.path.exists(id_file) and force != 'true':
        print(f"error: identity '{name}' already exists, use --force to overwrite",
              file=sys.stderr)
        sys.exit(1)
 
    os.makedirs(identities_dir, exist_ok=True)
    open(id_file, 'w').write(json.dumps(id_data, indent=2))
    print('identity')
 
 
def import_full(file, clients_dir, meta_dir, rules_dir, identities_dir,
                groups_dir, blocks_dir, policies_file, subnets_file,
                net_file, hosts_file, force):
    """Import a full backup bundle."""
    import base64, os, glob
 
    d = json.load(open(file))
    data = d['data']
    results = []
 
    # Peers
    for peer in data.get('peers', []):
        name = peer.get('name', '')
        if not name:
            continue
        try:
            conf_path = os.path.join(clients_dir, f"{name}.conf")
            if os.path.exists(conf_path) and force != 'true':
                results.append(f"skip:{name}")
                continue
            os.makedirs(clients_dir, exist_ok=True)
            conf = base64.b64decode(peer['conf']).decode()
            open(conf_path, 'w').write(conf)
 
            meta = peer.get('meta', {})
            if meta:
                os.makedirs(meta_dir, exist_ok=True)
                open(os.path.join(meta_dir, f"{name}.meta"), 'w').write(
                    json.dumps(meta, indent=2))
 
            blocks = peer.get('blocks', {})
            if blocks.get('is_blocked') and blocks.get('block_file'):
                os.makedirs(blocks_dir, exist_ok=True)
                block_data = base64.b64decode(blocks['block_file'])
                open(os.path.join(blocks_dir, f"{name}.block"), 'wb').write(block_data)
 
            results.append(f"peer:{name}")
        except Exception as e:
            results.append(f"error:{name}:{e}")
 
    # Rules
    os.makedirs(rules_dir, exist_ok=True)
    for rule in data.get('rules', []):
        name = rule.get('name', '')
        if name:
            open(os.path.join(rules_dir, f"{name}.rule"), 'w').write(
                json.dumps(rule, indent=2))
    results.append('rules')
 
    # Identities
    os.makedirs(identities_dir, exist_ok=True)
    for identity in data.get('identities', []):
        name = identity.get('name', '')
        if name:
            open(os.path.join(identities_dir, f"{name}.identity"), 'w').write(
                json.dumps(identity, indent=2))
    results.append('identities')
 
    # Groups
    os.makedirs(groups_dir, exist_ok=True)
    for grp in data.get('groups', []):
        name = grp.get('name', '')
        if name:
            open(os.path.join(groups_dir, f"{name}.group"), 'w').write(
                json.dumps(grp, indent=2))
    results.append('groups')

    # Block history
    bh_dir = os.path.join(os.path.dirname(groups_dir), 'block-history')
    os.makedirs(bh_dir, exist_ok=True)
    for bh in data.get('block_history', []):
        peer_name = bh.get('peer', '')
        if peer_name:
            open(os.path.join(bh_dir, f"{peer_name}.json"), 'w').write(
                json.dumps(bh, indent=2))
    if data.get('block_history'):
        results.append('block_history')
 
    # Flat JSON files
    for key, path in [('policies', policies_file), ('subnets', subnets_file),
                       ('services', net_file), ('hosts', hosts_file)]:
        section = data.get(key)
        if section is not None:
            open(path, 'w').write(json.dumps(section, indent=2))
            results.append(key)
 
    print('\n'.join(results))
 
 
def import_get_field(file, *keys):
    """Get a field from export JSON. Keys are dot-separated path."""
    d = json.load(open(file))
    val = d
    for k in keys:
        val = val.get(k, '')
        if not val:
            break
    print(val if val else '')