/**
 * Copyright (C) 2015 The Gravitee team (http://gravitee.io)
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *         http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package io.gravitee.repository.jdbc.management;

import io.gravitee.repository.exceptions.TechnicalException;
import io.gravitee.repository.jdbc.orm.JdbcObjectMapper;
import io.gravitee.repository.media.api.MediaRepository;
import io.gravitee.repository.media.model.Media;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.datasource.DataSourceUtils;
import org.springframework.stereotype.Repository;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.Types;
import java.util.Date;
import java.util.List;
import java.util.Optional;

import static io.gravitee.repository.jdbc.common.AbstractJdbcRepositoryConfiguration.escapeReservedWord;

/**
 * @author Guillaume GILLON
 */
@Repository
public class JdbcMediaRepository implements MediaRepository {

    @Autowired
    private JdbcTemplate jdbcTemplate;

    private static final Logger LOGGER = LoggerFactory.getLogger(JdbcMediaRepository.class);

    private static final JdbcObjectMapper ORM = JdbcObjectMapper.builder(Media.class, "media", "id")
            .addColumn("id", Types.NVARCHAR, String.class)
            .addColumn("type", Types.NVARCHAR, String.class)
            .addColumn("sub_type", Types.NVARCHAR, String.class)
            .addColumn("file_name", Types.NVARCHAR, String.class)
            .addColumn("size", Types.INTEGER, Long.class)
            .addColumn("data", Types.BLOB, byte[].class)
            .addColumn("created_at", Types.TIMESTAMP, Date.class)
            .addColumn("api", Types.NVARCHAR, String.class)
            .addColumn("hash", Types.NVARCHAR, String.class)
            .build();

    @Override
    public String save(Media media) throws TechnicalException {
        LOGGER.debug("JdbcMediaRepository.create({})", media);

        media.setCreatedAt(new Date());

        try {
            Connection conn = DataSourceUtils.getConnection(jdbcTemplate.getDataSource());
            conn.setAutoCommit(false);
            PreparedStatement ps = ORM.buildInsertPreparedStatementCreator(media).createPreparedStatement(conn);

            ps.execute();
            conn.commit();

            return media.getId();
        } catch (final Exception ex) {
            LOGGER.error("Failed to create media", ex);
            throw new TechnicalException("Failed to create media", ex);
        }
    }

    @Override
    public Optional<Media> findByHash(String hash, String mediaType) {
        LOGGER.debug("JdbcMediaRepository.findMediaBy({},{})", hash, mediaType);

        return this.findByHash(hash, null, mediaType);
    }

    @Override
    public Optional<Media> findByHash(String hash, String api, String mediaType) {
        LOGGER.debug("JdbcMediaRepository.findMediaBy({},{},{})", hash, mediaType, api);

        String sql;
        Object[] param;
        if (api != null) {
            sql = "select * from "+ escapeReservedWord("media")+" where hash = ? and type = ? and api = ?";
            param = new Object[]{hash, mediaType, api};
        } else {
            sql = "select * from media where hash = ? and type = ?";
            param = new Object[]{hash, mediaType};
        }

        List<Media> mediaList = jdbcTemplate.query(sql,
                ORM.getRowMapper(),
                param);

        return mediaList.stream().findFirst();
    }
}

@@ -1342,112 +1342,42 @@
 al;%0A
-%0A
 import 
-static io.gravitee.repository.jdbc.common.AbstractJdbcRepositoryConfiguration.escapeReservedWord
+java.util.stream.Collectors
 ;%0A%0A/
@@ -2341,18 +2341,644 @@
 lic 
-String sav
+Optional%3CMedia%3E findByHash(String hash, String mediaType) %7B%0A        LOGGER.debug(%22JdbcMediaRepository.findMediaBy(%7B%7D,%7B%7D)%22, hash, mediaType);%0A        return this.findByHashAndApi(hash, null, mediaType);%0A    %7D%0A%0A    @Override%0A    public List%3CMedia%3E findAllByApi(String api) %7B%0A        LOGGER.debug(%22JdbcMediaRepository.findAllByApi(%7B%7D)%22, api);%0A%0A        String sql = %22select * from media where api = ?%22;%0A        Object%5B%5D param = new Object%5B%5D%7Bapi%7D;%0A%0A        List%3CMedia%3E mediaList = jdbcTemplate.query(sql, ORM.getRowMapper(), param);%0A%0A        return mediaList.stream().collect(Collectors.toList());%0A    %7D%0A%0A    @Override%0A    public Media creat
 e(Me
@@ -3461,16 +3461,8 @@
 edia
-.getId()
 ;%0A  
@@ -3672,64 +3672,38 @@
 lic 
-Optional%3CMedia%3E findByHash(String hash, String mediaType
+void deleteAllByApi(String api
 ) %7B%0A
@@ -3748,56 +3748,40 @@
 ory.
-findMediaBy(%7B%7D,%7B%7D)%22, hash, mediaType
+deleteByApi(%7B%7D)%22, api
 );%0A
-%0A
         
 retu
@@ -3780,52 +3780,66 @@
     
-return this.findByHash(hash, null, mediaType
+jdbcTemplate.update(%22delete from media where api = ?%22, api
 );%0A 
@@ -3887,32 +3887,38 @@
 edia%3E findByHash
+AndApi
 (String hash, St
@@ -3989,31 +3989,36 @@
 ository.find
-MediaBy
+ByHashAndApi
 (%7B%7D,%7B%7D,%7B%7D)%22,
@@ -4150,40 +4150,13 @@
 rom 
-%22+ escapeReservedWord(%22
 media
-%22)+%22
  whe
@@ -4466,20 +4466,16 @@
         
-    
 ORM.getR
@@ -4486,20 +4486,16 @@
 pper(),%0A
-    
         

resolve API import/export