# Copyright (C) 2011 Canonical Ltd.
# Copyright (C) 2012, 2013 Hewlett-Packard Development Company, L.P.
#
# Author: Scott Moser <scott.moser@canonical.com>
# Author: Juerg Haefliger <juerg.haefliger@hp.com>
#
# This file is part of cloud-init. See LICENSE file for license information.

"""
Update Nic config
---------------
**Summary:** update interface

This module will update the system network interface config

**Internal name:** ``cc_update_nic``

**Module frequency:** per always

**Supported distros:** all

"""

import os
import json

from cloudinit.settings import PER_ALWAYS
from cloudinit import util
from cloudinit import net

frequency = PER_ALWAYS

def do_diff(log, newcfg, precfg_fn):
    with open(precfg_fn, 'r') as f:
        try:
            precfg=json.load(f)
        except:
            return newcfg

    log.debug("precfg %s"  %precfg)
    if precfg['version'] != newcfg['version']:
        return newcfg

    new = newcfg['config']
    old = precfg['config']
    add = []
    for n in new:
        found=0
        for o in old:
            if o['mac_address'] == n['mac_address']:
                found = 1
                break
        if not found:
            add.append(n)

    rm = []
    for o  in old:
        found = 0;
        for n in new:
            if o['mac_address'] == n['mac_address']:
                found=1
                break
        if not found:
            rm.append(o)

    if not add and not rm:
        return []
    log.debug("add new interface config %s" %add)
    log.debug("remove old interface config %s" %rm)
    return [{'version': newcfg['version'], 'config': add}, \
            {'version': newcfg['version'], 'config': rm}]

def handle(name, cfg, cloud, log, _args):
    if 'network' in cfg and net.is_disabled_cfg(cfg['network']):
        log.debug(("Configuration option 'network config disabled' is set,"
                   " not updating the nic interfaces config in module %s"), name)
        return
    netcfg_fn = "previous-netcfg"
    datasource = cloud.datasource
    distro = cloud.distro
    netcfg = datasource.network_config

    pre_fn = os.path.join(cloud.get_cpath("data"), netcfg_fn)
    if os.path.exists(pre_fn):
       diffcfg = do_diff(log, netcfg, pre_fn)
    else:
        diffcfg = [netcfg, {'version': netcfg['version'], 'config': []}]

    log.debug("diff interface config %s" %diffcfg)
    log.debug("network config %s" %netcfg)

    if not diffcfg:
        return
    try:
        log.debug("applying net config names for %s", diffcfg[0])
        distro.apply_network_config_names(diffcfg[0])
    except Exception as e:
        log.warning("Failed to rename devices: %s", e)
    try:
        distro.apply_nic_config(diffcfg, netcfg)
        with open(pre_fn, 'w') as f:
            json.dump(netcfg, f)
    except Exception as e:
        log.warning("nic update config failed: error %s" %str(e))
        return

# vi: ts=4 expandtab
