package org.opentosca.toscana.core.csar;

import java.io.InputStream;
import java.util.List;
import java.util.Optional;

import org.opentosca.toscana.core.parse.InvalidCsarException;
import org.opentosca.toscana.model.EffectiveModelFactory;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

@Service
public class CsarServiceImpl implements CsarService {

    private final static Logger logger = LoggerFactory.getLogger(CsarService.class.getName());

    private final CsarDao csarDao;
    private final EffectiveModelFactory effectiveModelFactory;

    @Autowired
    public CsarServiceImpl(CsarDao dao, EffectiveModelFactory effectiveModelFactory) {
        this.csarDao = dao;
        this.effectiveModelFactory = effectiveModelFactory;
    }

    @Override
    public Csar submitCsar(String identifier, InputStream csarStream) throws InvalidCsarException {
        Csar csar = csarDao.create(identifier, csarStream);
        try {
            validate(csar);
            return csar;
        } catch (InvalidCsarException e) {
            logger.warn("Failed to submit csar", e);
            // cleanup
            csarDao.delete(csar.getIdentifier());
            throw e;
        }
    }

    private void validate(Csar csar) throws InvalidCsarException {
        // TODO integrate winery parser as validator
        // test whether EffectiveModel can get created without throwing an error
        try {
            // test if conversion does evoke errors
            effectiveModelFactory.create(csar);
            // TODO improve error handling
        } catch (Exception e) {
            throw new InvalidCsarException(csar.getLog());
        }
    }

    @Override
    public void deleteCsar(Csar csar) {
        csarDao.delete(csar.getIdentifier());
    }

    @Override
    public List<Csar> getCsars() {
        List<Csar> list = csarDao.findAll();
        for (Csar csar : list) {
            try {
                validate(csar);
            } catch (InvalidCsarException e) {
                logger.error("Encountered invalid csar in repository.", csar, e);
                // TODO wait for discussion outcome, maybe cleanup disk
            }
        }
        return list;
    }

    @Override
    public Optional<Csar> getCsar(String identifier) {
        Optional<Csar> csar = csarDao.find(identifier);
        if (csar.isPresent()) {
            try {
                validate(csar.get());
            } catch (InvalidCsarException e) {
                logger.error("Encountered invalid csar in repository.", csar, e);
                // TODO wait for discussion outcome, maybe cleanup disk
            }
        }
        return csar;
    }
}

@@ -1303,24 +1303,69 @@
    %7D%0A    %7D%0A%0A
+    // this call is expensive, use with care%0A
     private 
@@ -1986,25 +1986,14 @@
     
-List%3CCsar%3E list =
+return
  csa
@@ -2012,337 +2012,8 @@
 ();%0A
-        for (Csar csar : list) %7B%0A            try %7B%0A                validate(csar);%0A            %7D catch (InvalidCsarException e) %7B%0A                logger.error(%22Encountered invalid csar in repository.%22, csar, e);%0A                // TODO wait for discussion outcome, maybe cleanup disk%0A            %7D%0A        %7D%0A        return list;%0A
     
@@ -2096,29 +2096,14 @@
     
-Optional%3CCsar%3E csar =
+return
  csa
@@ -2129,342 +2129,8 @@
 r);%0A
-        if (csar.isPresent()) %7B%0A            try %7B%0A                validate(csar.get());%0A            %7D catch (InvalidCsarException e) %7B%0A                logger.error(%22Encountered invalid csar in repository.%22, csar, e);%0A                // TODO wait for discussion outcome, maybe cleanup disk%0A            %7D%0A        %7D%0A        return csar;%0A
     

Remove unnecessary template validation (#458)