# gaf.netlist - gEDA Netlist Extraction and Generation
# Copyright (C) 1998-2010 Ales Hvezda
# Copyright (C) 1998-2010 gEDA Contributors (see ChangeLog for details)
# Copyright (C) 2013-2020 Roland Lutz
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software Foundation,
# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.

# Allegro netlist format

import errno, os, sys

def open_and_check(device):
    try:
        os.mkdir('devfiles')
    except OSError as e:
        mkdir_error = e
    else:
        mkdir_error = None

    try:
        f = open('devfiles/%s.txt' % device.lower(), 'w')
    except IOError as e:
        if e.errno == errno.ENOENT and mkdir_error is not None:
            sys.stderr.write("%s\n" % mkdir_error)
        else:
            sys.stderr.write("%s\n" % e)
        sys.stderr.write("The device files are expected to be "
                         "in the 'devfiles' directory.\n")
        sys.exit(3)

    return f

def output_netlist(f, package):
    f.write('(Device File generated by gEDA Allegro Netlister)\n')
    f.write('PACKAGE %s\n' % package.get_attribute('footprint', 'unknown'))
    f.write('CLASS %s\n' % package.get_attribute('class', 'unknown'))
    f.write('PINCOUNT %s\n' % package.get_attribute('pins', 'unknown'))
    altfoot = package.get_attribute('alt_foot', None)
    if altfoot is not None:
        f.write('PACKAGEPROP   ALT_SYMBOLS\n')
        f.write("'(%s)'\n" % altfoot)
    f.write('END\n')

def get_component_text(package, default):
    try:
        return package.get_attribute('value')
    except KeyError:
        try:
            return package.get_attribute('label')
        except KeyError:
            return package.get_attribute('device', default)

def run(f, netlist):
    f.write('(Allegro netlister by M. Ettus)\n')

    f.write('$PACKAGES\n')
    for package in reversed(netlist.packages):
        footprint = package.get_attribute('footprint', None)
        if footprint is not None:
            f.write(footprint)
        f.write('! %s! %s; %s\n' % (package.get_attribute('device', 'unknown'),
                                    get_component_text(package, 'unknown'),
                                    package.refdes))

    f.write('$NETS\n')
    for net in reversed(netlist.nets):
        f.write(net.name)
        f.write(';')
        f.write(',\n'.join(' %s.%s' % (pin.package.refdes, pin.number)
                           for pin in reversed(net.connections)) + '\n')

    f.write('$END\n')

    # write device files
    done = []
    for package in reversed(netlist.packages):
        device = package.get_attribute('device', 'unknown')
        if device in done:
            continue

        if f is sys.stdout:
            output_netlist(f, package)
        else:
            g = open_and_check(device)
            try:
                output_netlist(g, package)
            finally:
                g.close()
