# coding=utf-8
'''
Created on 01-10-2011

@author: lennyn
'''

from pybtex.database.input import bibtex as bibtex_input
from pybtex.database.output import bibtex as bibtex_output
from pybtex.database import BibliographyData
from StringIO import StringIO
import pdf_utils

def get_bib_data(bibtex_text):
    parser = bibtex_input.Parser()
    bib_data = parser.parse_stream(StringIO(bibtex_text))
    return bib_data

def get_bibtex_text(key, entry):
    return _get_bibtex_text(BibliographyData(entries={key: entry}, preamble=[]))

def _get_bibtex_text(bib_data):
    stream = StringIO()
    bibtex_output.Writer().write_stream(bib_data, stream)
    res = stream.getvalue()
    stream.close()
    return res.strip()

def get_bibtex4html(bibtex_text, id):
    bib_data = get_bib_data(bibtex_text)
    _resolve_crossrefs(bib_data)
    if pdf_utils.uploaded_file_exists(id):
        bib_data.entries[id].fields['pdf'] = pdf_utils.pubid2url(id)
    return get_bibtex_text(id, bib_data.entries[id])

def _resolve_crossrefs(bib_data):
    for _, entry in bib_data.entries.iteritems():
        if 'crossref' in entry.fields:
            entry_ref = bib_data.entries[entry.fields['crossref']]
            for field, value in entry_ref.fields.iteritems():
                if not field in entry.fields:
                    entry.fields[field] = value
            for personType in entry_ref.persons.iterkeys():
                if not personType in entry.persons:
                    entry.persons[personType] = entry_ref.persons[personType]
            del entry.fields['crossref']

def _add_to_bib_data(bib_data, pub):
    bib_data_tmp = get_bib_data(pub.get_bibtex(resolve_crossref=False))
    bib_data.entries[pub.id] = bib_data_tmp.entries[pub.id]
    if pub.crossref and not pub.crossref.id in bib_data.entries:
        _add_to_bib_data(bib_data, pub.crossref)

def get_bibtex_aggregate(publications):
    bib_data = BibliographyData(entries={}, preamble=[])
    for pub in publications:
        if not pub.id in bib_data.entries:
            _add_to_bib_data(bib_data, pub)
    return _get_bibtex_text(bib_data)
