"""API harvester for DataOne - for the SHARE project

Example query: https://cn.dataone.org/cn/v1/query/solr/?q=dateModified:[NOW-5DAY%20TO%20*]&rows=10
"""

from __future__ import unicode_literals

import re

import logging
from datetime import timedelta, date

from lxml import etree
from dateutil.parser import parse
from xml.etree import ElementTree

from nameparser import HumanName

from scrapi import requests
from scrapi import settings
from scrapi.base import XMLHarvester
from scrapi.util import copy_to_unicode
from scrapi.linter.document import RawDocument
from scrapi.base.helpers import compose, single_result, build_properties, date_formatter

logger = logging.getLogger(__name__)

DEFAULT_ENCODING = 'UTF-8'
DATAONE_SOLR_ENDPOINT = 'https://cn.dataone.org/cn/v1/query/solr/'


def process_doi(service_id, doc_doi):
    doi_re = '10\\.\\d{4}/\\w*\\.\\w*(/\\w*)?'

    doi_list = map(lambda x: x.replace('doi', ''), doc_doi) if isinstance(doc_doi, list) else [doc_doi.replace('doi', '')]

    for item in [service_id] + doi_list:
        try:
            return re.search(doi_re, item).group(0)
        except AttributeError:
            continue
    return ''


def process_contributors(author, submitters, contributors,
                         investigators):
    if not author:
        author = ''
    elif isinstance(author, list):
        author = author[0]

    if not isinstance(contributors, list):
        contributors = [contributors]

    if not isinstance(investigators, list):
        investigators = [investigators]

    unique_contributors = list(set([author] + contributors + investigators))

    if len(unique_contributors) < 1:
        return []

    # this is the index of the author in the unique_contributors list
    if author != '':
        author_index = unique_contributors.index(author)
    else:
        author_index = None

    # grabs the email if there is one, this should go with the author index
    email = ''
    for submitter in submitters:
        if '@' in submitter:
            email = submitter

    contributor_list = []
    for index, contributor in enumerate(unique_contributors):
        if author_index is not None and index == author_index:
            # if contributor == NAME and email != '':
            #     # TODO - maybe add this back in someday
            #       sometimes this yields really weird names like mjg4
            #     # TODO - names not always perfectly lined up with emails...
            #     contributor = name_from_email(email)
            name = HumanName(contributor)
            contributor_dict = {
                'name': contributor,
                'givenName': name.first,
                'additionalName': name.middle,
                'familyName': name.last,
            }
            if email:
                contributor_dict['email'] = email
            contributor_list.append(contributor_dict)
        else:
            name = HumanName(contributor)
            contributor_list.append({
                'name': contributor,
                'givenName': name.first,
                'additionalName': name.middle,
                'familyName': name.last,
            })

    return contributor_list


class DataOneHarvester(XMLHarvester):
    short_name = 'dataone'
    long_name = 'DataONE: Data Observation Network for Earth'
    url = 'https://www.dataone.org/'

    namespaces = {}

    record_encoding = None

    schema = {
        'otherProperties': build_properties(
            ('authorGivenName', ("str[@name='authorGivenName']/node()")),
            ('authorSurName', ("str[@name='authorSurName']/node()")),
            ('authoritativeMN', ("str[@name='authoritativeMN']/node()")),
            ('checksum', ("str[@name='checksum']/node()")),
            ('checksumAlgorithm', ("str[@name='checksumAlgorithm']/node()")),
            ('datasource', ("str[@name='datasource']/node()")),
            ('datePublished', ("date[@name='datePublished']/node()")),
            ('dateUploaded', ("date[@name='dateUploaded']/node()")),
            ('pubDate', ("date[@name='pubDate']/node()")),
            ('updateDate', ("date[@name='updateDate']/node()")),