import os
import re

from citeproc import CitationStylesStyle, CitationStylesBibliography
from citeproc import Citation, CitationItem
from citeproc import formatter
from citeproc.source.json import CiteProcJSON

from website.preprints.model import PreprintService
from website.project.model import Node
from website.settings import CITATION_STYLES_PATH


def display_absolute_url(node):
    url = node.absolute_url
    if url is not None:
        return re.sub(r'https?:', '', url).strip('/')


def preprint_csl(preprint, node):
    csl = node.csl

    csl['id'] = preprint._id
    csl['publisher'] = preprint.provider.name
    csl['URL'] = display_absolute_url(preprint)

    if csl.get('DOI'):
        csl.pop('DOI')

    doi = preprint.article_doi
    if doi:
        csl['DOI'] = doi

    return csl


def render_citation(node, style='apa'):
    """Given a node, return a citation"""
    if isinstance(node, Node):
        data = [node.csl, ]
    elif isinstance(node, PreprintService):
        csl = preprint_csl(node, node.node)
        data = [csl, ]
    else:
        raise ValueError

    bib_source = CiteProcJSON(data)

    bib_style = CitationStylesStyle(os.path.join(CITATION_STYLES_PATH, style), validate=False)

    bibliography = CitationStylesBibliography(bib_style, bib_source, formatter.plain)

    citation = Citation([CitationItem(node._id)])

    bibliography.register(citation)

    def warn(citation_item):
        pass

    bibliography.cite(citation, warn)
    bib = bibliography.bibliography()

    cit = unicode(bib[0] if len(bib) else '')

    if '..' not in node.csl['title']:
        cit = cit.replace('..', '.')
        cit = cit.replace('..', '.')

    if '  ' != node.csl['title']:
        cit = cit.replace('  ', ' ')
        cit = cit.replace('  ', ' ')

    return cit

@@ -356,437 +356,105 @@
 def 
-display_absolute_url(node):%0A    url = node.absolute_url%0A    if url is not None:%0A        return re.sub(r'https?:', '', url).strip('/')%0A%0A%0Adef preprint_csl(preprint, node):%0A    csl = node.csl%0A%0A    csl%5B'id'%5D
+clean_up_common_errors(cit):%0A    cit
  = 
-p
 re
-print._id%0A    csl%5B'publisher'%5D = preprint.provider.name%0A    csl%5B'URL'%5D = display_absolute_url(preprin
+.sub(r%22%5C.+%22, '.', ci
 t)%0A
-%0A
     
-if csl.get('DOI'):%0A        csl.pop('DOI')%0A%0A    doi
+cit
  = 
-p
 re
-print.article_doi%0A    if doi:%0A        csl%5B'DOI'%5D = doi%0A
+.sub(r%22 +%22, ' ', cit)
 %0A   
@@ -462,18 +462,18 @@
 return c
-sl
+it
 %0A%0A%0Adef r
@@ -1238,22 +1238,15 @@
     
-if '..' not in
+title =
  nod
@@ -1251,32 +1251,61 @@
 ode.csl%5B'title'%5D
+%0A    if cit.count(title) == 1
 :%0A        cit = 
@@ -1302,108 +1302,140 @@
     
-cit
+i
  = cit.
-replace('..', '.')%0A        cit = cit.replace('..', '.'
+index(title)%0A        prefix = clean_up_common_errors(cit%5B0:i%5D
 )%0A
-%0A
     
-if '  ' != node.csl%5B'
+    suffix = clean_up_common_errors(cit%5Bi + len(
 title
-'%5D:
+):%5D)
 %0A   
@@ -1449,66 +1449,104 @@
 t = 
-cit.replace('  ', ' ')%0A        cit = cit.replace('  ', ' '
+prefix + title + suffix%0A    elif cit.count(title) == 0:%0A        cit = clean_up_common_errors(cit
 )%0A%0A 

use regex and account for title with ' ' and '..'