// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements.  See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership.  The ASF licenses this file
// to you 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 com.cloud.keystore;

import java.sql.PreparedStatement;
import java.util.Comparator;
import java.util.List;

import javax.ejb.Local;

import com.cloud.utils.db.DB;
import com.cloud.utils.db.GenericDaoBase;
import com.cloud.utils.db.SearchBuilder;
import com.cloud.utils.db.SearchCriteria;
import com.cloud.utils.db.SearchCriteria.Op;
import com.cloud.utils.db.Transaction;
import com.cloud.utils.exception.CloudRuntimeException;

import edu.emory.mathcs.backport.java.util.Collections;

@Local(value={KeystoreDao.class})
public class KeystoreDaoImpl extends GenericDaoBase<KeystoreVO, Long> implements KeystoreDao {
    protected final SearchBuilder<KeystoreVO> FindByNameSearch;
    protected final SearchBuilder<KeystoreVO> CertChainSearch;

	public KeystoreDaoImpl() {
		FindByNameSearch = createSearchBuilder();
		FindByNameSearch.and("name", FindByNameSearch.entity().getName(), Op.EQ);
		FindByNameSearch.done();
		
		CertChainSearch = createSearchBuilder();
		CertChainSearch.and("key", CertChainSearch.entity().getKey(), Op.NULL);
		CertChainSearch.done();
	}
	
	@Override
	public List<KeystoreVO> findCertChain() {
		SearchCriteria<KeystoreVO> sc =  CertChainSearch.create();
		List<KeystoreVO> ks = listBy(sc);
		Collections.sort(ks, new Comparator() { public int compare(Object o1, Object o2) {
			Integer seq1 = ((KeystoreVO)o1).getIndex();
			Integer seq2 = ((KeystoreVO)o2).getIndex();
			return seq1.compareTo(seq2);
		}});
		return ks;
	}
	
	@Override
	public KeystoreVO findByName(String name) {
		assert(name != null);
		
		SearchCriteria<KeystoreVO> sc =  FindByNameSearch.create();
		sc.setParameters("name", name);
		return findOneBy(sc);
	}
	
	@Override
	@DB
	public void save(String name, String certificate, String key, String domainSuffix) {
		Transaction txn = Transaction.currentTxn();
		try {
			txn.start();
			
			String sql = "INSERT INTO keystore (`name`, `certificate`, `key`, `domain_suffix`) VALUES (?, ?, ?, ?) ON DUPLICATE KEY UPDATE `certificate`=?, `key`=?, `domain_suffix`=?";
			PreparedStatement pstmt = txn.prepareAutoCloseStatement(sql);
			pstmt.setString(1, name);
			pstmt.setString(2, certificate);
			pstmt.setString(3, key);
			pstmt.setString(4, domainSuffix);
			pstmt.setString(5, certificate);
			pstmt.setString(6, key);
			pstmt.setString(7, domainSuffix);

			pstmt.executeUpdate();
			txn.commit();
		} catch(Exception e) {
			txn.rollback();
			throw new CloudRuntimeException("Unable to save certificate under name " + name + " due to exception", e);
		}
	}
	
	@Override
	@DB
	public void save(String alias, String certificate, Integer index, String domainSuffix) {
		KeystoreVO ks = this.findByName(alias);
		if (ks != null) {
			ks.setCertificate(certificate);
			ks.setName(alias);
			ks.setIndex(index);
			ks.setDomainSuffix(domainSuffix);
			this.update(ks.getId(), ks);
		} else {
			KeystoreVO newks = new KeystoreVO();
			newks.setCertificate(certificate);
			newks.setName(alias);
			newks.setIndex(index);
			newks.setDomainSuffix(domainSuffix);
			this.persist(newks);
		}
	}
}
