package org.ambraproject.rhino.service.impl;

import com.google.common.base.Preconditions;
import org.ambraproject.rhino.identity.ArticleIngestionIdentifier;
import org.ambraproject.rhino.identity.ArticleRevisionIdentifier;
import org.ambraproject.rhino.model.ArticleIngestion;
import org.ambraproject.rhino.model.ArticleRevision;
import org.ambraproject.rhino.model.ArticleTable;
import org.ambraproject.rhino.service.ArticleCrudService;
import org.ambraproject.rhino.service.ArticleRevisionWriteService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.orm.hibernate3.HibernateTemplate;

import java.util.Optional;

public class ArticleRevisionWriteServiceImpl implements ArticleRevisionWriteService {

  @Autowired
  private ArticleCrudService articleCrudService;
  @Autowired
  private HibernateTemplate hibernateTemplate;

  @Override
  public ArticleRevision writeRevision(ArticleRevisionIdentifier revisionId, ArticleIngestionIdentifier ingestionId) {
    Preconditions.checkArgument(revisionId.getArticleIdentifier().equals(ingestionId.getArticleIdentifier()));
    ArticleIngestion ingestion = articleCrudService.readIngestion(ingestionId);

    ArticleTable article = ingestion.getArticle();
    Optional<ArticleRevision> previousLatest = articleCrudService.getLatestRevision(article);

    ArticleRevision newRevision = articleCrudService.getRevision(revisionId)
        .map((ArticleRevision revision) -> {
          revision.setIngestion(ingestion);
          hibernateTemplate.update(revision);
          return revision;
        })
        .orElseGet(() -> {
          ArticleRevision revision = new ArticleRevision();
          revision.setIngestion(ingestion);
          revision.setRevisionNumber(revisionId.getRevision());
          hibernateTemplate.save(revision);
          return revision;
        });

    if (!previousLatest.isPresent() || previousLatest.get().getRevisionNumber() <= newRevision.getRevisionNumber()) {
      refreshForLatestRevision(newRevision);
    }

    return newRevision;
  }

  @Override
  public void deleteRevision(ArticleRevisionIdentifier revisionId) {
    ArticleRevision revision = articleCrudService.readRevision(revisionId);
    ArticleTable article = revision.getIngestion().getArticle();

    ArticleRevision latestRevision = articleCrudService.getLatestRevision(article)
        .orElseThrow(RuntimeException::new); // should be guaranteed to exist because at least one revision exists
    boolean deletingLatest = latestRevision.equals(revision);

    hibernateTemplate.delete(revision);

    if (deletingLatest) {
      articleCrudService.getLatestRevision(article)
          .ifPresent(this::refreshForLatestRevision);
      // else, we deleted the only revision
    }
  }

  private void refreshForLatestRevision(ArticleRevision newlyLatestRevision) {
    // TODO: Implement
  }

}

@@ -1412,181 +1412,8 @@
 Id)%0A
-        .map((ArticleRevision revision) -%3E %7B%0A          revision.setIngestion(ingestion);%0A          hibernateTemplate.update(revision);%0A          return revision;%0A        %7D)%0A
     
@@ -1499,52 +1499,8 @@
 ();%0A
-          revision.setIngestion(ingestion);%0A
     
@@ -1573,39 +1573,23 @@
     
-hibernateTemplate.save(
+return 
 revision
 );%0A 
@@ -1580,25 +1580,24 @@
 urn revision
-)
 ;%0A          
@@ -1598,36 +1598,99 @@
     
-  return revis
+%7D);%0A    newRevision.setIngestion(ingest
 ion
+)
 ;%0A    
-    %7D
+hibernateTemplate.saveOrUpdate(newRevision
 );%0A%0A

Refactor duplication out of if-else