/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package com.arrebol.taxiservicios.controller.catalog;

//import com.amazonaws.auth.AWSCredentials;
//import com.amazonaws.auth.AWSStaticCredentialsProvider;
//import com.amazonaws.auth.BasicAWSCredentials;
//import com.amazonaws.services.s3.AmazonS3;
//import com.amazonaws.services.s3.AmazonS3ClientBuilder;
//import com.amazonaws.services.s3.model.ObjectMetadata;
//import com.amazonaws.services.s3.model.PutObjectRequest;
import com.arrebol.taxiservicios.controller.connection.ConnectionManager;
import com.arrebol.taxiservicios.controller.util.HibernateUtil;
import com.arrebol.taxiservicios.model.catalog.Location;
import com.arrebol.taxiservicios.model.core.User;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.Serializable;
import java.util.Date;
import java.util.List;
import java.util.UUID;
import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.CriteriaUpdate;
import javax.persistence.criteria.Path;
import javax.persistence.criteria.Root;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.hibernate.HibernateException;
import org.hibernate.Session;
import org.hibernate.Transaction;
import org.primefaces.model.UploadedFile;

/**
 *
 * @author Oscar
 */
public class LocationController extends ConnectionManager implements Serializable {

    
     public Location getLocationById(String locationId) {
        logger.info("getPersonById");

        Location location = null;
        Transaction transaction = null;
        try {
            Session session = HibernateUtil.getSessionFactory().getCurrentSession();
            transaction = session.beginTransaction();

            location = session.get(Location.class, locationId);

            transaction.commit();
            logger.info("Location " + location);
        } catch (HibernateException e) {
            logger.error("Location cannot be loaded " + locationId, e);
            rollback(transaction);
        } catch (Exception e) {
            logger.error("Method getLocatonById(" + locationId + ") ", e);
            rollback(transaction);
        }
        return location;
    }
    
    public List<Location> fillLocationDatatable() {

        Transaction transaction = null;
        List<Location> result = null;

        try {
            logger.info("Searching all locations..");
            Session session = HibernateUtil.getSessionFactory().getCurrentSession();
            transaction = session.beginTransaction();
            CriteriaBuilder builder = session.getCriteriaBuilder();

            CriteriaQuery<Location> criteria = builder.createQuery(Location.class);
            Root<Location> root = criteria.from(Location.class);
            /*
            Path<String> idPath = root.get("id");
            Path<String> namePath = root.get("name");
            Path<User> userPath = root.get("createdBy");

            criteria.select(
                    builder.construct(Location.class, idPath, namePath, userPath));*/

            criteria.where(builder.equal(root.get("active"), Boolean.TRUE));
            criteria.orderBy(builder.asc(root.get("name")));

            result = session.createQuery(criteria).getResultList();

            logger.info("Total of locations found : " + (null == result ? -1 : result.size()));
            transaction.commit();
        } catch (HibernateException e) {
            logger.error("Can not load list of locations ", e);
            rollback(transaction);
        } catch (Exception e) {
            logger.error("Method fillLocationDatatable of location", e);
            rollback(transaction);
        }

        return result;
    }

    public void delete(Location location) {

        Transaction transaction = null;
        try {
            Session session = HibernateUtil.getSessionFactory().getCurrentSession();
            transaction = session.beginTransaction();
            CriteriaBuilder builder = session.getCriteriaBuilder();

            if (location.getId() != null) {

                CriteriaUpdate<Location> update = builder.createCriteriaUpdate(Location.class);
                Root<Location> rootPerson = update.from(Location.class);

                update.set(("active"), Boolean.FALSE);

                update.where(builder.equal(rootPerson.get("id"), location.getId()));

                int total = session.createQuery(update).executeUpdate();

                if (1 == total) {
                    logger.info("The location was deleted - " + location.getId());
                    transaction.commit();

                } else {
                    logger.error("location can not be updated " + location.getId());
                    transaction.rollback();
                }

            }
        } catch (HibernateException e) {
            logger.error("The location can not be deleted - " + location, e);
            rollback(transaction);
        } catch (Exception e) {
            logger.error("Method  delete(" + location + ")", e);
            rollback(transaction);
        }
    }

    public boolean addLocation(Location location, String userName) {
        logger.info("addLocation");
        boolean success = false;

        Transaction transaction = null;
        try {
            Session session = HibernateUtil.getSessionFactory().getCurrentSession();
            transaction = session.beginTransaction();
            CriteriaBuilder builder = session.getCriteriaBuilder();

            if (location.getId() != null) {
                CriteriaUpdate<Location> update = builder.createCriteriaUpdate(Location.class);
                Root<Location> root = update.from(Location.class);

                update.set("name", location.getName());
                update.set("address", location.getAddress());
                update.set("suburb", location.getSuburb());
                update.set("municipality", location.getMunicipality());
                update.set("state", location.getState());
                update.set("postalCode", location.getPostalCode());
                update.set("completeAddress", location.getCompleteAddress());
                update.set("phone", location.getPhone());
                update.set("rfc", location.getRfc());
                update.set("taxRegime", location.getTaxRegime());
                update.set("gerente", location.getGerente());
                update.set("mail", location.getMail());
                update.set("businessName", location.getBusinessName());                              
                update.set("lastUpdatedBy", new User(userName, ""));
                update.set("lastUpdatedOn", new Date());
                update.set("maxPerson", location.getMaxPerson());
                

                update.where(builder.equal(root.get("id"), location.getId()));

                session.createQuery(update).executeUpdate();

                logger.info("The location was edited - " + location);

            } else {
                location.setId(UUID.randomUUID().toString());
                location.setCreatedBy(new User(userName, ""));
                location.setCreatedOn(new Date());
                location.setActive(true);
                session.save(location);
                logger.info("location saved " + location.getId());
            }

            transaction.commit();
            
            

            success = true;
        } catch (HibernateException e) {
            logger.error("Location can not be added ", e);
            rollback(transaction);
        } catch (Exception e) {
            logger.error("Method addLocation() ", e);
            rollback(transaction);
        }
        return success;
    }
    
    public boolean updateLogo(Location location, String userName) {
        logger.info("addLocation");
        boolean success = false;

        Transaction transaction = null;
        try {
            Session session = HibernateUtil.getSessionFactory().getCurrentSession();
            transaction = session.beginTransaction();
            CriteriaBuilder builder = session.getCriteriaBuilder();

            
                CriteriaUpdate<Location> update = builder.createCriteriaUpdate(Location.class);
                Root<Location> root = update.from(Location.class);

                
                update.set("logo", location.getLogo());
                

                update.where(builder.equal(root.get("id"), location.getId()));

                session.createQuery(update).executeUpdate();

                logger.info("The location was edited - " + location);

           

            transaction.commit();
            
            

            success = true;
        } catch (HibernateException e) {
            logger.error("Location can not be added ", e);
            rollback(transaction);
        } catch (Exception e) {
            logger.error("Method addLocation() ", e);
            rollback(transaction);
        }
        return success;
    }
    
    public boolean updatePrinter(Location location, String userName) {
        logger.info("addLocation");
        boolean success = false;
        Transaction transaction = null;
        try {
            Session session = HibernateUtil.getSessionFactory().getCurrentSession();
            transaction = session.beginTransaction();
            CriteriaBuilder builder = session.getCriteriaBuilder();

                CriteriaUpdate<Location> update = builder.createCriteriaUpdate(Location.class);
                Root<Location> root = update.from(Location.class);

            update.set("printer", location.getPrinter());                            
            update.set("lastUpdatedBy", new User(userName, ""));
            update.set("lastUpdatedOn", new Date());
                update.where(builder.equal(root.get("id"), location.getId()));

                session.createQuery(update).executeUpdate();
            logger.info("The printer for the location was updated- " + location);

            transaction.commit();
            success = true;
        } catch (HibernateException e) {
            logger.error("The printer for the location not updated ", e);
            rollback(transaction);
        } catch (Exception e) {
            logger.error("Method updatePrinter() ", e);
            rollback(transaction);
        }
        return success;
    }
    
    public void addLocationCertificate(String accessKey, String secretKey, String region, String bucket,
            UploadedFile certificate, UploadedFile certificateKey,InputStream certificateInputStream, InputStream keyInputStream, String certificatePass, 
            Location location, String idUser) throws IOException {

        initS3(accessKey, secretKey, region);


       /* if (!getS3Client().doesBucketExistV2(bucket)) {
            logger.info("Bucket name is not available."
                    + " Try again with a different Bucket name.");
            return;
        }*/

/*        ObjectMetadata metaDataCertificate = new ObjectMetadata();
        metaDataCertificate.setContentLength(certificate.getSize());
        
        ObjectMetadata metaDataKey = new ObjectMetadata();
        metaDataKey.setContentLength(certificateKey.getSize());
        
        getS3Client().putObject(new PutObjectRequest(bucket,location.getId()+"-"+certificate.getFileName(),certificateInputStream,metaDataCertificate));

        getS3Client().putObject(new PutObjectRequest(bucket,location.getId()+"-"+certificateKey.getFileName(),keyInputStream,metaDataKey));
        
        Transaction transaction = null;
        try {  
            Session session = HibernateUtil.getSessionFactory().getCurrentSession();
            transaction = session.beginTransaction();
            CriteriaBuilder builder = session.getCriteriaBuilder();
            
            
            CriteriaUpdate<Location> update = builder.createCriteriaUpdate(Location.class);
            Root<Location> root = update.from(Location.class);

                update.set("certificate",location.getId()+"-"+certificate.getFileName());
                update.set("certificateKey",location.getId()+"-"+certificateKey.getFileName());
                update.set("certificatePassword", location.getCertificatePassword());
                
                update.set("lastUpdatedBy", new User(idUser, ""));
            update.set("lastUpdatedOn", new Date());

            update.where(builder.equal(root.get("id"), location.getId()));

            session.createQuery(update).executeUpdate();
            
                logger.info("The location was edited - " + location);

            

            transaction.commit();

         
        } catch (HibernateException e) {
            logger.error("Location can not be added ", e);
            rollback(transaction);
        } catch (Exception e) {
            logger.error("Method addLocation() ", e);
            rollback(transaction);
        }*/

        }

    public void initS3(String accessKey, String secretKey, String region) {
        /*setCredientials(new BasicAWSCredentials(
                accessKey,
                secretKey
        ));

        setS3Client(AmazonS3ClientBuilder
                .standard()
                .withCredentials(new AWSStaticCredentialsProvider(getCredientials()))
                .withRegion(region)
                .build());*/

    }

    private static final long serialVersionUID = 1020525241432403643L;

   // private AWSCredentials credientials;
   // private AmazonS3 s3Client;

    final Logger logger = LogManager.getLogger(LocationController.class);

    public LocationController() {
    }

    /*public AWSCredentials getCredientials() {
        return credientials;
}

    public void setCredientials(AWSCredentials credientials) {
        this.credientials = credientials;
    }

    public AmazonS3 getS3Client() {
        return s3Client;
    }

    public void setS3Client(AmazonS3 s3Client) {
        this.s3Client = s3Client;
    }*/

}
