import re,io,json,sys
from .Review import Review

class Paper:
  """A paper class, which contains relevant fields and a list of reviews"""
  def __init__(self, TITLE, ABSTRACT, ID, REVIEWS, AUTHORS=None, CONFERENCE=None, ACCEPTED=None, SCORE=None,
         PUBLICATION_TYPE=None, SCIENCEPARSE=None, KEYWORDS=None, AUTHOR_EMAILS=None, DATE_OF_SUBMISSION=None,
         SUBJECTS=None,COMMENTS=None,VERSION=None,HISTORIES=None):
    self.TITLE = TITLE
    self.ABSTRACT = re.sub("\\n", " ", ABSTRACT)
    self.ID = ID
    self.AUTHORS = AUTHORS
    self.REVIEWS = REVIEWS
    self.SCIENCEPARSE = SCIENCEPARSE
    self.CONFERENCE = CONFERENCE
    self.ACCEPTED = ACCEPTED
    self.SCORE = SCORE
    self.PUBLICATION_TYPE = PUBLICATION_TYPE
    self.KEYWORDS = KEYWORDS
    self.AUTHOR_EMAILS = AUTHOR_EMAILS
    self.DATE_OF_SUBMISSION = DATE_OF_SUBMISSION

    # additional properties for arxiv papers
    self.SUBJECTS = SUBJECTS
    self.COMMENTS = COMMENTS
    self.VERSION = VERSION
    self.HISTORIES = HISTORIES #[(version,date,link,comments),...]

  @staticmethod
  def from_softconf_dump(json_file, conference=None):
    with io.open(json_file, "r", encoding="utf8") as ifh:
      json_str = ifh.read()

    # print (json_str)
    json_data = json.loads(json_str)["submissions"]

    papers = []
    for i in range(len(json_data)):
      reviews = []
      for k in range(len(json_data[i]["reviews"])):
        # print(json_data[i]["reviews"][k])
        review_data = []

        review = Review.from_json_object(json_data[i]["reviews"][k], k==i==0)
        #review = None

        reviews.append(review)

      authors = json_data[i]["authors"] if "authors" in json_data[i] else None
      score = json_data[i]["score"] if "score" in json_data[i] else None
      accepted = json_data[i]["accepted"] if "accepted" in json_data[i] else None
      publication_type = json_data[i]["publication_type"] if "publication_type" in json_data[i] else None
      keywords = json_data[i]["KEYWORDS"] if "KEYWORDS" in json_data[i] else None
      author_emails = json_data[i]["AUTHOR_EMAILS"] if "AUTHOR_EMAILS" in json_data[i] else None
      date_of_submission = json_data[i]["DATE_OF_SUBMISSION"] if "DATE_OF_SUBMISSION" in json_data[i] else None

      paper = Paper(json_data[i]["title"], json_data[i]["abstract"], json_data[i]["id"], reviews, authors, \
              conference, accepted, score, publication_type, None, keywords, author_emails, \
              date_of_submission)

      papers.append(paper)
      # break

    return papers

  @staticmethod
  def from_json(json_filename, from_annotated = False):
    paper = Paper('', '', None, [])

    datas = []
    with io.open(json_filename, mode='rt', encoding='utf8') as json_file:
      for line in json_file:
        try:
          data = json.loads(line.strip())
          datas.append(data)
        except Exception as e:
          print(line)
          continue
    if len(datas)==0: return None
    data = datas[-1]

    # Read required fields.
    assert 'title' in data
    assert 'abstract' in data
    paper.TITLE = data['title']
    paper.ABSTRACT = data['abstract']

    if 'id' in data:
      if data['id'] == "":
        paper.ID = json_filename.split("/")[-1].split(".")[0]
      else:
        paper.ID = data['id']
    else:
      paper.ID = json_filename.split("/")[-1].split(".")[0]

    # Read optional fields.
    paper.AUTHORS = data['authors'] if 'authors' in data else None
    paper.CONFERENCE = data['conference'] if 'conference' in data else None
    paper.ACCEPTED = data['accepted'] if 'accepted' in data else None
    paper.SCORE = data['score'] if 'score' in data else None
    paper.PUBLICATION_TYPE = data['publication_type'] if 'publication_type' in data else None
    paper.SCIENCEPARSE = data['scienceparse'] if 'scienceparse' in data else None
    paper.KEYWORDS = data['keywords'] if 'keywords' in data else None
    paper.AUTHOR_EMAILS = data['author_emails'] if 'author_emails' in data else None

    paper.DATE_OF_SUBMISSION = data['DATE_OF_SUBMISSION'] if 'DATE_OF_SUBMISSION' in data else None

    paper.SUBJECTS = data['SUBJECTS'] if 'SUBJECTS' in data else None
    paper.COMMENTS = data['COMMENTS'] if 'COMMENTS' in data else None
    paper.VERSION = data['VERSION'] if 'VERSION' in data else None
    paper.HISTORIES = data['histories'] if 'histories' in data else None

    # Read reviews (mandatory).
    assert 'reviews' in data
    for review_data in data['reviews']:
      review = Review.from_json_object(review_data)
      paper.REVIEWS.append(review)
    return paper



  def to_json_object(self):
    data = dict()

    data["title"] = self.get_title()
    data["abstract"] = self.get_abstract()
    data["id"] = self.get_id()

    if self.AUTHORS is not None:
      data["authors"] = self.get_authors()

    if self.CONFERENCE is not None:
      data["conference"] = self.get_conference()

    if self.ACCEPTED is not None:
      data["accepted"] = self.get_accepted()

    if self.SCORE is not None:
      data["SCORE"] = self.get_score()

    if self.PUBLICATION_TYPE is not None:
      data["publication_type"] = self.get_publication_type()

    if self.SCIENCEPARSE is not None:
      data["SCIENCEPARSE"] = self.get_scienceparse()

    if self.AUTHOR_EMAILS is not None:
      data["AUTHOR_EMAILS"] = self.get_author_emails()

    if self.KEYWORDS is not None:
      data["KEYWORDS"] = self.get_keywords()

    if self.DATE_OF_SUBMISSION is not None:
      data["DATE_OF_SUBMISSION"] = self.get_date_of_submission()

    data["reviews"] = []

    for r in self.get_reviews():
      data["reviews"].append(r.to_json_object())

    # added for arxiv papers

    if self.SUBJECTS is not None:
      data["SUBJECTS"] = self.get_subjects()

    if self.COMMENTS is not None:
      data["COMMENTS"] = self.get_comments()

    if self.VERSION is not None:
      data["VERSION"] = self.get_version()

    data["histories"] = []
    if self.HISTORIES is not None:
      for h in self.get_histories():
        if h is not None:
          v,d,l,p = h
          data["histories"].append((v,d,l, p if p else None))

    return data

  def to_json(self, json_file, mode='a'):

    data = self.to_json_object()

    with open(json_file, mode) as ofh:
      json.dump(data, ofh)
      ofh.write("\n")


  def get_subjects(self):
    return self.SUBJECTS
  def get_comments(self):
    return self.COMMENTS
  def get_version(self):
    return self.VERSION
  def get_histories(self):
    return self.HISTORIES


  def get_title(self):
    return self.TITLE

  def get_abstract(self):
    return self.ABSTRACT

  def abstract_contains_a_term(self, term):
    return (term in self.ABSTRACT)

  def get_id(self):
    return self.ID

  def get_authors(self):
    return self.AUTHORS

  def get_reviews(self):
    return self.REVIEWS

  def get_scienceparse(self):
    return self.SCIENCEPARSE

  def get_title_len(self):
    return len(self.TITLE)

  def get_abstract_len(self):
    return len(self.ABSTRACT)

  def get_conference(self):
    return self.CONFERENCE

  def get_score(self):
    return self.SCORE

  def get_accepted(self):
    return self.ACCEPTED

  def get_publication_type(self):
    return self.PUBLICATION_TYPE

  def get_author_emails(self):
    return self.AUTHOR_EMAILS

  def get_keywords(self):
    return self.KEYWORDS

  def get_date_of_submission(self):
    return self.DATE_OF_SUBMISSION

def main(args):
  papers = Paper.from_softconf_dump('../../data/conll16/reviews.json')
  for paper in papers:
    paper.to_json('../../data/conll16_new/{}.json'.format(paper.ID))

if __name__ == "__main__":
  sys.exit(main(sys.argv))
