/*
 * 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 org.apache.openmeetings.mail;

import org.apache.openmeetings.db.dao.basic.ConfigurationDao;
import org.apache.openmeetings.util.OpenmeetingsVariables;
import org.red5.logging.Red5LoggerFactory;
import org.slf4j.Logger;
import org.smslib.Message.MessageEncodings;
import org.smslib.OutboundMessage;
import org.smslib.Service;
import org.smslib.http.BulkSmsHTTPGateway;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.task.TaskExecutor;

/**
 * 
 * @author iarkh
 * 
 */

public class SMSHandler {

	private static final Logger log = Red5LoggerFactory.getLogger(
			SMSHandler.class, OpenmeetingsVariables.webAppRootKey);

	@Autowired
	protected ConfigurationDao configurationDao;
	@Autowired
	protected TaskExecutor taskExecutor;

	private BulkSmsHTTPGateway gateway = null;
	
	private boolean checkBalance() throws Exception {
		if (gateway == null) {
			String smsProvider = configurationDao.getConfValue("sms.provider", String.class, null);
			String smsUsername = configurationDao.getConfValue("sms.username", String.class, null);
			String smsUserpass = configurationDao.getConfValue("sms.userpass", String.class, null);

			if (smsProvider == null || smsProvider.length() == 0 ||
					smsUsername == null || smsUsername.length() == 0) {
				log.error("SMS Provider is not configured properly!");
				return false;
			}
			gateway = new BulkSmsHTTPGateway(smsProvider, smsUsername, smsUserpass);
			gateway.setOutbound(true);
			Service.getInstance().addGateway(gateway);
			Service.getInstance().startService();
		}
		return gateway.queryBalance() >= 1; 
	}
	
	public boolean sendSMS(String phone, String subj, long language_id) {
		try {
			taskExecutor.execute(new SMSSenderTask(phone, subj, language_id));
			return true;
		} catch (Exception ex) {
			log.error("sendSMS", ex);
			return false;
		}
	}
	
	protected class SMSSenderTask implements Runnable {
		private final String phone;
		private final String subject;
		private long language_id;

		public SMSSenderTask(String phone, String subject, long language_id) {
			this.phone = phone;
			this.subject = subject;
			this.language_id = language_id;
		}

		public void run() {
			this.send();
		}

		/**
		 * Sending an SMS with the given values.
		 * @return <code>true</code> if sms was sent successfully, <code>false</code> otherwise.
		 */
		public boolean send() {
			try {
				log.debug("SMS sending to: " + phone + ", subject is: " + subject);
				if (checkBalance()) {
					OutboundMessage msg = new OutboundMessage(phone, subject);
					if (language_id != 1) {
						msg.setEncoding(MessageEncodings.ENCUCS2);
					}
					return Service.getInstance().sendMessage(msg);
				} else {
					log.error("Error: insufficient funds on SMS provider account!");
					return false; 
				}
			} catch (Exception ex) {
				log.error("Error sending sms: ", ex);
				return false;
			} 
		}
	}
}
