from share.normalize import ctx
from share.normalize import tools
from share.normalize.parsers import Parser


class Link(Parser):
    url = tools.RunPython('format_link', ctx)
    type = tools.RunPython('get_link_type', ctx)

    def get_link_type(self, link):
        if 'doi' in link:
            return 'doi'
        if self.config.home_page and self.config.home_page in link:
            return 'provider'
        return 'misc'

    def format_link(self, link):
        link_type = self.get_link_type(link)
        if link_type == 'doi':
            return tools.DOI().execute(link)
        return link


class ThroughLinks(Parser):
    link = tools.Delegate(Link, ctx)


class Organization(Parser):
    name = ctx


class Affiliation(Parser):
    pass


class Person(Parser):

    given_name = tools.ParseName(ctx.name).first
    family_name = tools.ParseName(ctx.name).last
    additional_name = tools.ParseName(ctx.name).middle
    suffix = tools.ParseName(ctx.name).suffix

    affiliations = tools.Map(
        tools.Delegate(Affiliation.using(entity=tools.Delegate(Organization))),
        tools.Try(ctx['arxiv:affiliation'])
    )


class Contributor(Parser):
    order_cited = ctx('index')
    cited_name = ctx.name
    person = tools.Delegate(Person, ctx)


class Tag(Parser):
    name = ctx['@term']


class ThroughTags(Parser):
    tag = tools.Delegate(Tag, ctx)


class Subject(Parser):
    name = ctx


class ThroughSubjects(Parser):
    subject = tools.Delegate(Subject, ctx)


class Preprint(Parser):

    title = ctx.entry.title
    description = ctx.entry.summary
    date_published = tools.ParseDate(ctx.entry.published)
    date_updated = tools.ParseDate(ctx.entry.updated)
    contributors = tools.Map(tools.Delegate(Contributor), ctx.entry.author)

    links = tools.Map(
        tools.Delegate(ThroughLinks),
        tools.Try(ctx.entry['arxiv:doi']),
        ctx.entry.id
    )

    subjects = tools.Map(
        tools.Delegate(ThroughSubjects),
        tools.Subjects(
            tools.RunPython(
                'get_subjects',
                tools.Concat(tools.Try(ctx.entry.category))
            )
        )
    )

    tags = tools.Map(
        tools.Delegate(ThroughTags),
        ctx.entry.category
    )

    class Extra:

        resource_id = ctx.entry.id
        journal_ref = tools.Try(ctx.entry['arxiv:journal_ref'])
        comment = tools.Try(ctx.entry['arxiv:comment'])
        primary_category = tools.Try(ctx.entry['arxiv:primary_category'])

    def get_subjects(self, link):
        return list(map((lambda category: category['@term']), link))

@@ -110,20 +110,30 @@
 %0A%0Aclass 
-Link
+WorkIdentifier
 (Parser)
@@ -140,17 +140,17 @@
 :%0A    ur
-l
+i
  = tools
@@ -154,489 +154,126 @@
 ols.
-RunPython('format_link', ctx)%0A    type = tools.RunPython('get_link_type', ctx)%0A%0A    def get_link_type(self, link):%0A        if 'doi' in link:%0A            return 'doi'%0A        if self.config.home_page and self.config.home_page in link:%0A            return 'provider'%0A        return 'misc'%0A%0A    def format_link(self, link):%0A        link_type = self.get_link_type(link)%0A        if link_type == 'doi':%0A            return tools.DOI().execute(link)%0A        return link%0A%0A%0Aclass ThroughLinks
+IRI(ctx)%0A%0A%0Aclass Organization(Parser):%0A    schema = tools.GuessAgentType(ctx)%0A%0A    name = ctx%0A%0A%0Aclass IsAffiliatedWith
 (Par
@@ -282,20 +282,23 @@
 r):%0A    
-link
+related
  = tools
@@ -311,101 +311,26 @@
 ate(
-Link, ctx)%0A%0A%0Aclass Organization(Parser):%0A    name = ctx%0A%0A%0Aclass Affiliation(Parser):%0A    pass
+Organization, ctx)
 %0A%0A%0Ac
@@ -354,224 +354,46 @@
 r):%0A
-%0A
     
-given_
 name = 
-tools.ParseName(ctx.name).first%0A    family_name = tools.ParseName(ctx.name).last%0A    additional_name = tools.ParseName(ctx.name).middle%0A    suffix = tools.ParseName(ctx.name).suffix%0A%0A    affiliation
+ctx.name%0A%0A    related_agent
 s = 
@@ -426,24 +426,26 @@
 elegate(
+Is
 Affiliat
 ion.usin
@@ -440,54 +440,14 @@
 liat
-ion.using(entity=tools.Delegate(Organization))
+edWith
 ),%0A 
@@ -504,23 +504,19 @@
 %0Aclass C
-ontribu
+rea
 tor(Pars
@@ -561,20 +561,18 @@
   cited_
-name
+as
  = ctx.n
@@ -583,14 +583,13 @@
     
-person
+agent
  = t
@@ -650,25 +650,16 @@
 me = ctx
-%5B'@term'%5D
 %0A%0A%0Aclass
@@ -857,17 +857,16 @@
 arser):%0A
-%0A
     titl
@@ -921,16 +921,17 @@
 summary%0A
+%0A
     date
@@ -1042,456 +1042,222 @@
     
-contributors = tools.Map(tools.Delegate(Contributor), ctx.entry.author)%0A%0A    links = tools.Map(%0A        tools.Delegate(ThroughLinks),%0A        tools.Try(ctx.entry%5B'arxiv:doi'%5D),%0A        ctx.entry.id%0A    )%0A%0A    subjects = tools.Map(%0A        tools.Delegate(ThroughSubjects),%0A        tools.Subjects(%0A            tools.RunPython(%0A                'get_subjects',%0A                tools.Concat(tools.Try(ctx.entry.category))%0A            )%0A        )
+# free_to_read_type%0A    # free_to_read_date%0A    # rights%0A    # language%0A    subjects = tools.Map(%0A        tools.Delegate(ThroughSubjects),%0A        tools.Subjects(tools.Map(ctx%5B'@term'%5D, ctx.entry.category)),
 %0A    )%0A
-%0A
     
@@ -1318,16 +1318,40 @@
 %0A       
+ tools.Map(ctx%5B'@term'%5D,
  ctx.ent
@@ -1361,22 +1361,269 @@
 category
+),
 %0A    )
+%0A    # venues%0A    related_agents = tools.Concat(%0A        tools.Map(tools.Delegate(Creator), ctx.entry.author),%0A    )%0A    # related_works%0A    identifiers = tools.Map(tools.Delegate(WorkIdentifier), tools.Try(ctx.entry%5B'arxiv:doi'%5D), ctx.entry.id)
 %0A%0A    cl
@@ -1633,17 +1633,16 @@
  Extra:%0A
-%0A
         
@@ -1866,108 +1866,4 @@
 '%5D)%0A
-%0A    def get_subjects(self, link):%0A        return list(map((lambda category: category%5B'@term'%5D), link))%0A

Update arxiv