/**
 *  Copyright (C) 2010 Cloud.com, Inc.  All rights reserved.
 * 
 * This software is licensed under the GNU General Public License v3 or later.
 * 
 * It is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or any later version.
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 * 
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 * 
 * @author-aj
 */

package com.cloud.netapp;

import java.io.IOException;
import java.net.UnknownHostException;
import java.rmi.ServerException;
import java.util.ArrayList;
import java.util.ConcurrentModificationException;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.StringTokenizer;

import javax.ejb.Local;
import javax.naming.ConfigurationException;

import netapp.manage.NaAPIFailedException;
import netapp.manage.NaAuthenticationException;
import netapp.manage.NaElement;
import netapp.manage.NaException;
import netapp.manage.NaProtocolException;
import netapp.manage.NaServer;

import org.apache.log4j.Logger;

import com.cloud.exception.InvalidParameterValueException;
import com.cloud.exception.ResourceAllocationException;
import com.cloud.exception.ResourceInUseException;
import com.cloud.netapp.dao.LunDao;
import com.cloud.netapp.dao.PoolDao;
import com.cloud.netapp.dao.VolumeDao;
import com.cloud.utils.component.Inject;
import com.cloud.utils.db.DB;
import com.cloud.utils.db.Transaction;
import com.cloud.utils.exception.CloudRuntimeException;

@Local(value = { NetappManager.class })
public class NetappManagerImpl implements NetappManager
{   
	public enum Algorithm { roundrobin,leastfull }

    protected String _name;
    
    public static final Logger s_logger = Logger.getLogger(NetappManagerImpl.class.getName());
    @Inject public VolumeDao _volumeDao;
    @Inject public PoolDao _poolDao;
    @Inject public LunDao _lunDao;
    private NetappAllocator _netappAllocator = null;
    
    /**
     * Default constructor
     */
    public NetappManagerImpl(){
    }
    
    @Override
    public  void createPool(String poolName, String algorithm) throws InvalidParameterValueException
    {	
		if(s_logger.isDebugEnabled())
			s_logger.debug("Request --> createPool ");
		
    	PoolVO pool = null;
    	validAlgorithm(algorithm);
    	try {
    		pool = new PoolVO(poolName, algorithm);
    		_poolDao.persist(pool); 
    		
    		if(s_logger.isDebugEnabled())
    			s_logger.debug("Response --> createPool:success");
    		
    	} catch (CloudRuntimeException cre){
    		pool = _poolDao.findPool(poolName);
        	if (pool != null) {
        		throw new InvalidParameterValueException("Duplicate Pool Name");
        	} else {
        		throw cre;
        	}
    	}
    }
    
    /**
     * This method validates the algorithm used for allocation of the volume
     * @param algorithm -- algorithm type
     * @throws InvalidParameterValueException
     */
    private void validAlgorithm(String algorithm) throws InvalidParameterValueException {
    	//TODO: use enum
    	if(!algorithm.equalsIgnoreCase("roundrobin") && !algorithm.equalsIgnoreCase("leastfull")){
    		throw new InvalidParameterValueException("Unknown algorithm " + algorithm);
    	}
    }
    
    /**
     * Utility method to get the netapp server object
     * @param serverIp -- ip address of netapp box
     * @param userName -- username
     * @param password -- password
     * @return
     * @throws UnknownHostException
     */
    private NaServer getServer(String serverIp, String userName, String password) throws UnknownHostException {
    	//Initialize connection to server, and
		//request version 1.3 of the API set
    	NaServer s = new NaServer(serverIp, 1, 3); 
		s.setStyle(NaServer.STYLE_LOGIN_PASSWORD);
		s.setAdminUser(userName, password); 
    	
		return s;
    }
    
    @Override
    public void modifyPool(String poolName, String algorithm) throws InvalidParameterValueException
    {	
    	validAlgorithm(algorithm);
    	PoolVO pool = _poolDao.findPool(poolName);
    	
    	if(pool == null){
    		throw new InvalidParameterValueException("Cannot find pool " + poolName);
    	}
    	
    	validAlgorithm(algorithm);
    	
    	pool.setAlgorithm(algorithm);
    	pool.setName(poolName);
    	
    	_poolDao.update(pool.getId(), pool);
    }
    
    @Override
    public void deletePool(String poolName) throws InvalidParameterValueException, ResourceInUseException
    {
		if(s_logger.isDebugEnabled())
			s_logger.debug("Request --> deletePool ");
		
    	PoolVO pool = _poolDao.findPool(poolName);
    	if(pool == null){
    		throw new InvalidParameterValueException("Cannot find pool " + poolName);
    	}
    	//check if pool is empty
    	int volCount = _volumeDao.listVolumes(poolName).size();

    	if(volCount==0){
    		_poolDao.remove(pool.getId());
		if(s_logger.isDebugEnabled())
			s_logger.debug("Request --> deletePool: Success ");
    		
    	} else {
    		throw new ResourceInUseException("Cannot delete non-empty pool");
    	}
    }
    
    @Override
    public List<PoolVO> listPools(){
    	return _poolDao.listAll();
    }
    
    /**
     * This method destroys the volume on netapp filer
     * @param ipAddress -- ip address of filer
     * @param aggrName -- name of containing aggregate
     * @param volName -- name of volume to destroy
     * @throws ResourceInUseException 
     * @throws NaException
     * @throws IOException
     * @throws NaProtocolException 
     * @throws NaAPIFailedException 
     * @throws NaAuthenticationException 
     */
    @Override
    @DB
    public void destroyVolumeOnFiler(String ipAddress, String aggrName, String volName) throws ServerException, InvalidParameterValueException, ResourceInUseException{
		NaElement xi0;
    	NaElement xi1;
 		NetappVolumeVO volume = null;
		
 		volume = _volumeDao.findVolume(ipAddress, aggrName, volName);
 		
 		if(volume==null)
 		{
 			s_logger.warn("The volume does not exist in our system");
 			throw new InvalidParameterValueException("The given tuple:"+ipAddress+","+aggrName+","+volName+" doesn't exist in our system");
 		}

 		List<LunVO> lunsOnVol = _lunDao.listLunsByVolId(volume.getId());
 		
 		if(lunsOnVol!=null && lunsOnVol.size()>0)
 		{
 			s_logger.warn("There are luns on the volume");
 			throw new ResourceInUseException("There are luns on the volume");
 		}
 		
 		final Transaction txn = Transaction.currentTxn();
 		txn.start();
 		PoolVO pool = _poolDao.findById(volume.getPoolId());
 		if (pool == null) {
 			throw new InvalidParameterValueException("Failed to find pool for given volume");
 			//FIXME: choose a better exception. this is a db integrity exception
 		}
 		pool = _poolDao.acquireInLockTable(pool.getId());
 		if (pool == null) {
 			throw new ConcurrentModificationException("Failed to acquire lock on pool " + volume.getPoolId());
 		}
		NaServer s = null;
		try 
		{
			s = getServer(volume.getIpAddress(), volume.getUsername(), volume.getPassword());
			//bring the volume down
			xi0 = new NaElement("volume-offline");
			xi0.addNewChild("name",volName);
			s.invokeElem(xi0);

			//now destroy it
			xi1 = new NaElement("volume-destroy");
			xi1.addNewChild("name",volName);
			s.invokeElem(xi1);

			//now delete from our records
			_volumeDao.remove(volume.getId());
			txn.commit();

		} catch (UnknownHostException uhe) {
			s_logger.warn("Unable to delete volume on filer " , uhe);
			throw new ServerException("Unable to delete volume on filer", uhe);
		}catch (NaAPIFailedException naf) {
			s_logger.warn("Unable to delete volume on filer " , naf);
			if( naf.getErrno() == 13040 ){
				s_logger.info("Deleting the volume: " + volName);
				_volumeDao.remove(volume.getId());
				txn.commit();
			}
			
			throw new ServerException("Unable to delete volume on filer", naf);
		} 
		catch (NaException nae) {
			txn.rollback();
			s_logger.warn("Unable to delete volume on filer " , nae);
			throw new ServerException("Unable to delete volume on filer", nae);
		} catch (IOException ioe) {
			txn.rollback();
			s_logger.warn("Unable to delete volume on filer " , ioe);
			throw new ServerException("Unable to delete volume on filer", ioe);
		}
		finally
		{
			if (pool != null) {
				_poolDao.releaseFromLockTable(pool.getId());
			}
			if (s != null)
				s.close();
		}


			
    }
    
    /**
     * This method creates a volume on netapp filer
     * @param ipAddress -- ip address of the filer
     * @param aggName -- name of aggregate
     * @param poolName -- name of pool
     * @param volName -- name of volume
     * @param volSize -- size of volume to be created
     * @param snapshotPolicy -- associated snapshot policy for volume
     * @param snapshotReservation -- associated reservation for snapshots
     * @param username -- username
     * @param password -- password
     * @throws UnknownHostException
     * @throws InvalidParameterValueException 
     */
    @Override
    @DB
	public void createVolumeOnFiler(String ipAddress, String aggName, String poolName, String volName, String volSize, String snapshotPolicy, Integer snapshotReservation, String username, String password) throws  UnknownHostException,  ServerException, InvalidParameterValueException 
	{
  
		if(s_logger.isDebugEnabled())
			s_logger.debug("Request --> createVolume "+"serverIp:"+ipAddress);
		
		boolean snapPolicy = false;
		boolean snapshotRes = false;
		boolean volumeCreated = false;
		
		NaServer s = getServer(ipAddress, username, password); 
		
		NaElement xi = new NaElement("volume-create");
		xi.addNewChild("volume", volName);
		xi.addNewChild("containing-aggr-name",aggName);
		xi.addNewChild("size",volSize);
		
		NaElement xi1 = new NaElement("snapshot-set-reserve");
		if(snapshotReservation!=null)
		{
			snapshotRes = true;
			xi1.addNewChild("percentage",snapshotReservation.toString());
			xi1.addNewChild("volume",volName);
		}
		
		NaElement xi2 = new NaElement("snapshot-set-schedule");
		
		if(snapshotPolicy!=null)
		{
			snapPolicy = true;
			
			String weeks = null;
			String days = null;
			String hours = null;
			String whichHours = null;
			String minutes = null;
			String whichMinutes = null;
			
			StringTokenizer s1 = new StringTokenizer(snapshotPolicy," ");
			
			//count=4: weeks days hours@csi mins@csi
			//count=3: weeks days hours@csi
			//count=2: weeks days
			//count=1: weeks
	
			if(s1.hasMoreTokens())
			{
				weeks = s1.nextToken();
			}
			if(weeks!=null && s1.hasMoreTokens())
			{
				days = s1.nextToken();
			}
			if(days!=null && s1.hasMoreTokens())
			{
				String[] hoursArr = s1.nextToken().split("@");
				hours = hoursArr[0];
				whichHours = hoursArr[1];
			}
			if(hours!=null && s1.hasMoreTokens())
			{
				String[] minsArr = s1.nextToken().split("@");
				minutes = minsArr[0];
				whichMinutes = minsArr[1];
			}
			
			if(weeks!=null)
				xi2.addNewChild("weeks",weeks);
			if(days!=null)
				xi2.addNewChild("days",days);
			if(hours!=null)
				xi2.addNewChild("hours",hours);
			if(minutes!=null)
				xi2.addNewChild("minutes",minutes);
			xi2.addNewChild("volume",volName);
			
			if(whichHours!=null)
				xi2.addNewChild("which-hours",whichHours);
			if(whichMinutes!=null)
				xi2.addNewChild("which-minutes",whichMinutes);
		}
		Long volumeId = null;
		
		final Transaction txn = Transaction.currentTxn();
		txn.start();
		NetappVolumeVO volume = null;
		volume = _volumeDao.findVolume(ipAddress, aggName, volName);
		
		if(volume != null) {
			throw new InvalidParameterValueException("The volume for the given ipAddress/aggregateName/volumeName tuple already exists");
		}
		PoolVO pool = _poolDao.findPool(poolName);
		if (pool == null) {
			throw new InvalidParameterValueException("Cannot find pool " + poolName);
		}
		pool = _poolDao.acquireInLockTable(pool.getId());
		if (pool == null) {
			s_logger.warn("Failed to acquire lock on pool " + poolName);
			throw new ConcurrentModificationException("Failed to acquire lock on pool " + poolName);
		}
		volume = new NetappVolumeVO(ipAddress, aggName, pool.getId(), volName, volSize, "", 0, username, password,0,pool.getName());
		volume = _volumeDao.persist(volume);
		
		volumeId = volume.getId();
		try {
			s.invokeElem(xi);
			volumeCreated = true;
			
			if(snapshotRes)
			{
				s.invokeElem(xi1);
				volume.setSnapshotReservation(snapshotReservation);
				_volumeDao.update(volumeId, volume);
			}

			if(snapPolicy)
			{
				s.invokeElem(xi2);
				volume.setSnapshotPolicy(snapshotPolicy);
				_volumeDao.update(volumeId, volume);
			}	
			txn.commit();
		} catch (NaException nae) {
			//zapi call failed, log and throw e
			s_logger.warn("Failed to create volume on the netapp filer:", nae);
			txn.rollback();
			if(volumeCreated) {
				try {
					deleteRogueVolume(volName, s);//deletes created volume on filer
				} catch (NaException e) {
					s_logger.warn("Failed to cleanup created volume whilst rolling back on the netapp filer:", e);
					throw new ServerException("Unable to create volume via cloudtools."+"Failed to cleanup created volume on netapp filer whilst rolling back on the cloud db:", e);
				} catch (IOException e) {
					s_logger.warn("Failed to cleanup created volume whilst rolling back on the netapp filer:", e);
					throw new ServerException("Unable to create volume via cloudtools."+"Failed to cleanup created volume on netapp filer whilst rolling back on the cloud db:", e);
				}
			}
			throw new ServerException("Unable to create volume", nae);
		} catch (IOException ioe) {
			s_logger.warn("Failed to create volume on the netapp filer:", ioe);
			txn.rollback();
			if(volumeCreated) {
				try {
					deleteRogueVolume(volName, s);//deletes created volume on filer
				} catch (NaException e) {
					s_logger.warn("Failed to cleanup created volume whilst rolling back on the netapp filer:", e);
					throw new ServerException("Unable to create volume via cloudtools."+"Failed to cleanup created volume on netapp filer whilst rolling back on the cloud db:", e);
				} catch (IOException e) {
					s_logger.warn("Failed to cleanup created volume whilst rolling back on the netapp filer:", e);
					throw new ServerException("Unable to create volume via cloudtools."+"Failed to cleanup created volume on netapp filer whilst rolling back on the cloud db:", e);
				}
			}
			throw new ServerException("Unable to create volume", ioe);
		}
		finally{
			if (s != null) 
				s.close();
			if (pool != null) 
				_poolDao.releaseFromLockTable(pool.getId());
			
		}
	}
	
    /**
     * This method is primarily used to cleanup volume created on the netapp filer, when createVol api command fails at snapshot reservation. 
     * We roll back the db record, but the record on the netapp box still exists. We clean up that record using this helper method.
     * @param volName
     * @param s -- server reference
     * @throws NaException
     * @throws IOException
     */
    private void deleteRogueVolume(String volName, NaServer s) throws NaException, IOException {
		//bring the volume down
		NaElement xi0 = new NaElement("volume-offline");
		xi0.addNewChild("name",volName);
		s.invokeElem(xi0);

		//now destroy it
		NaElement xi1 = new NaElement("volume-destroy");
		xi1.addNewChild("name",volName);
		s.invokeElem(xi1);
    }
    
	/**
	 * This method lists all the volumes by pool name
	 * @param poolName
	 * @return -- volumes in that pool
	 */
    @Override
	public List<NetappVolumeVO> listVolumesOnFiler(String poolName){
		
    	List<NetappVolumeVO> vols = _volumeDao.listVolumesAscending(poolName);
    	
    	for(NetappVolumeVO vol : vols){
    		try {
				String snapScheduleOnFiler = returnSnapshotSchedule(vol);
				vol.setSnapshotPolicy(snapScheduleOnFiler);
				
			} catch (ServerException e) {
				s_logger.warn("Error trying to get snapshot schedule for volume"+vol.getVolumeName());
			}
    	}
		return vols;
	}

    
    /**
     * Utility method to return snapshot schedule for a volume
     * @param vol -- volume for the snapshot schedule creation
     * @return -- the snapshot schedule
     * @throws ServerException
     */
    private String returnSnapshotSchedule(NetappVolumeVO vol) throws ServerException{

		NaElement xi = new NaElement("snapshot-get-schedule");
		xi.addNewChild("volume", vol.getVolumeName());
		NaServer s = null;
		try {
			s = getServer(vol.getIpAddress(), vol.getUsername(), vol.getPassword());
			NaElement xo = s.invokeElem(xi);
			String weeks = xo.getChildContent("weeks");
			String days = xo.getChildContent("days");
			String hours = xo.getChildContent("hours");
			String minutes = xo.getChildContent("minutes");
			String whichHours = xo.getChildContent("which-hours");
			String whichMinutes = xo.getChildContent("which-minutes");
			
			StringBuilder sB = new StringBuilder();
			sB.append(weeks).append(" ").append(days).append(" ").append(hours).append("@").append(whichHours).append(" ").append(minutes).append("@").append(whichMinutes);
			return sB.toString();
		} catch (NaException nae) {
			s_logger.warn("Failed to get volume size ", nae);
			throw new ServerException("Failed to get volume size", nae);
		} catch (IOException ioe) {
			s_logger.warn("Failed to get volume size ", ioe);
			throw new ServerException("Failed to get volume size", ioe);
		}
		finally{
			if (s != null)
				s.close();
		}
    }
	/**
	 * This method returns the ascending order list of volumes based on their ids
	 * @param poolName -- name of pool
	 * @return -- ascending ordered list of volumes based on ids
	 */
    @Override
	public List<NetappVolumeVO> listVolumesAscending(String poolName){
		return _volumeDao.listVolumesAscending(poolName);
	}
	
	/**
	 * This method returns the available size on the volume in terms of bytes
	 * @param volName -- name of volume
	 * @param userName -- username
	 * @param password -- password
	 * @param serverIp -- ip address of filer
	 * @throws UnknownHostException 
	 * @return-- available size on the volume in terms of bytes; return -1 if volume is offline
	 * @throws ServerException
	 */
    @Override
	public long returnAvailableVolumeSize(String volName, String userName, String password, String serverIp) throws ServerException {	
		long availableSize = 0;

		NaElement xi = new NaElement("volume-list-info");
		xi.addNewChild("volume", volName);
		NaServer s = null;
		String volumeState = null;
		try {
			s = getServer(serverIp, userName, password);
			NaElement xo = s.invokeElem(xi);
			List volList = xo.getChildByName("volumes").getChildren();
			Iterator volIter = volList.iterator();
			while(volIter.hasNext()){
				NaElement volInfo=(NaElement)volIter.next();
				availableSize = volInfo.getChildLongValue("size-available", -1);
				volumeState = volInfo.getChildContent("state");
			}
			
			if (volumeState != null) {
				return volumeState.equalsIgnoreCase("online") ? availableSize : -1; //return -1 if volume is offline
			}
			else {
				//catch all
				//volume state unreported
				return -1; // as good as volume offline
			}
				
			
		} catch (NaException nae) {
			s_logger.warn("Failed to get volume size ", nae);
			throw new ServerException("Failed to get volume size", nae);
		} catch (IOException ioe) {
			s_logger.warn("Failed to get volume size ", ioe);
			throw new ServerException("Failed to get volume size", ioe);
		}
		finally{
			if (s != null)
				s.close();
		}
	}

	/**
	 * This method creates a lun on the netapp filer
	 * @param poolName -- name of the pool
	 * @param lunSize -- size of the lun to be created
	 * @return -- lun path 
	 * @throws IOException
	 * @throws ResourceAllocationException 
	 * @throws NaException
	 */
    @Override
    @DB
	public String[] createLunOnFiler(String poolName, Long lunSize) throws  ServerException, InvalidParameterValueException, ResourceAllocationException {
    	String[] result = new String[3];
		StringBuilder lunName = new StringBuilder("lun-");
		LunVO lun = null;
    	final Transaction txn = Transaction.currentTxn();
		txn.start();
    	PoolVO pool = _poolDao.findPool(poolName);
    	
    	if(pool == null){
    		throw new InvalidParameterValueException("Cannot find pool " + poolName);
    	}

    	if (lunSize <= 0) {
    		throw new InvalidParameterValueException("Please specify a valid lun size in Gb");
    	}
    	
    	String algorithm = pool.getAlgorithm();
    	NetappVolumeVO selectedVol = null;

    	//sanity check
    	int numVolsInPool = _volumeDao.listVolumes(poolName).size();

    	if (numVolsInPool == 0)
    	{
    		throw new InvalidParameterValueException("No volumes exist in the given pool");
    	}
    	pool = _poolDao.acquireInLockTable(pool.getId());
    	if (pool == null) {
    		s_logger.warn("Failed to acquire lock on the pool " + poolName);
    		return result;
    	}
    	NaServer s = null;

    	try 
    	{
    		if(algorithm == null || algorithm.equals(Algorithm.roundrobin.toString()))
    		{
    			selectedVol = _netappAllocator.chooseVolumeFromPool(poolName, lunSize);
    		}
    		else if(algorithm.equals(Algorithm.leastfull.toString()))
    		{

    			selectedVol = _netappAllocator.chooseLeastFullVolumeFromPool(poolName, lunSize);
    		}

    		if(selectedVol == null)
    		{
    			throw new ResourceAllocationException("Could not find a suitable volume to create lun on");
    		}

    		if(s_logger.isDebugEnabled())
    			s_logger.debug("Request --> createLun "+"serverIp:"+selectedVol.getIpAddress());
    		
    		StringBuilder exportPath = new StringBuilder("/vol/");
    		exportPath.append(selectedVol.getVolumeName());
    		exportPath.append("/");

    		lun = new LunVO(exportPath.toString(), selectedVol.getId(), lunSize, "","");
    		lun = _lunDao.persist(lun);
    		
    		//Lun id created: 6 digits right justified eg. 000045
    		String lunIdStr = lun.getId().toString();
    		String zeroStr = "000000";
    		int length = lunIdStr.length();
    		int offset = 6-length;
    		StringBuilder lunIdOnPath = new StringBuilder();
    		lunIdOnPath.append(zeroStr.substring(0, offset));
    		lunIdOnPath.append(lunIdStr);
    		exportPath.append("lun-").append(lunIdOnPath.toString());
    		
    		lunName.append(lunIdOnPath.toString());
    		
    		//update lun name
    		lun.setLunName(lunName.toString());
    		_lunDao.update(lun.getId(), lun);
    		
    		NaElement xi;
    		NaElement xi1;

    		long lSizeBytes = 1L*lunSize*1024*1024*1024; //This prevents integer overflow
    		Long lunSizeBytes = new Long(lSizeBytes);
    		
    		s = getServer(selectedVol.getIpAddress(), selectedVol.getUsername(),selectedVol.getPassword()); 

    		//create lun
    		xi = new NaElement("lun-create-by-size");
    		xi.addNewChild("ostype","linux");
    		xi.addNewChild("path",exportPath.toString());
    		xi.addNewChild("size", (lunSizeBytes.toString()));
    		
    		s.invokeElem(xi);	

    		try
    		{
	    		//now create an igroup
				xi1 = new NaElement("igroup-create");
				xi1.addNewChild("initiator-group-name", lunName .toString());
				xi1.addNewChild("initiator-group-type", "iscsi");
				xi1.addNewChild("os-type", "linux");
				s.invokeElem(xi1);
    		}catch(NaAPIFailedException e)
    		{
    			if(e.getErrno() == 9004)
    			{
    				//igroup already exists hence no error
    				s_logger.warn("Igroup already exists");
    			}
    		}

    		//get target iqn
			NaElement xi4 = new NaElement("iscsi-node-get-name");
			NaElement xo = s.invokeElem(xi4);
			String iqn = xo.getChildContent("node-name");
			
			lun.setTargetIqn(iqn);
			_lunDao.update(lun.getId(), lun);
			
			//create lun mapping
			//now map the lun to the igroup
			NaElement xi3 = new NaElement("lun-map");
			xi3.addNewChild("force", "true");
			xi3.addNewChild("initiator-group", lunName.toString());
			xi3.addNewChild("path", lun.getPath() + lun.getLunName());
			
			xi3.addNewChild("lun-id", lunIdStr);
			s.invokeElem(xi3);
    		
    		txn.commit();
    		//set the result
    		result[0] = lunName.toString();//lunname
    		result[1] = iqn;//iqn
    		result[2] =  selectedVol.getIpAddress();
    		
    		return result;
    		
    	}
    	catch (NaAPIFailedException naf)
    	{
			if(naf.getErrno() == 9023){ //lun is already mapped to this group
				result[0] = lunName.toString();//lunname;
				result[1] = lun.getTargetIqn();//iqn
				result[2] = selectedVol.getIpAddress();
				return result;
			}			
			if(naf.getErrno() == 9024){ //another lun mapped at this group
				result[0] = lunName.toString();//lunname;
				result[1] = lun.getTargetIqn();//iqn
				result[2] = selectedVol.getIpAddress();
				return result;
			}	
    	}
    	catch (NaException nae) 
    	{
    		txn.rollback();
    		throw new ServerException("Unable to create LUN", nae);
    	} 
    	catch (IOException ioe) 
    	{
    		txn.rollback();
    		throw new ServerException("Unable to create LUN", ioe);
    	}
    	finally
    	{
    		if (pool != null) {
    			_poolDao.releaseFromLockTable(pool.getId());
    		}
    		if (s != null) {
    			s.close();
    		}
    	}

    	return result;
	}
	
	/**
	 * This method destroys a lun on the netapp filer
	 * @param lunName -- name of the lun to be destroyed
	 */
    @Override
    @DB
	public void destroyLunOnFiler(String lunName) throws InvalidParameterValueException, ServerException{
		
		final Transaction txn = Transaction.currentTxn();
		txn.start();
		
		LunVO lun = _lunDao.findByName(lunName);
		
		if(lun == null)
			throw new InvalidParameterValueException("Cannot find lun");
		
		NetappVolumeVO vol = _volumeDao.acquireInLockTable(lun.getVolumeId());
		if (vol == null) {
			s_logger.warn("Failed to lock volume id= " + lun.getVolumeId());
			return;
		}
		NaServer s = null;
		try {
			s = getServer(vol.getIpAddress(), vol.getUsername(), vol.getPassword()); 
			
			if(s_logger.isDebugEnabled())
				s_logger.debug("Request --> destroyLun "+":serverIp:"+vol.getIpAddress());
			
			try {
				//Unmap lun
				NaElement xi2 = new NaElement("lun-unmap");
				xi2.addNewChild("initiator-group", lunName);
				xi2.addNewChild("path", lun.getPath()+lun.getLunName());
				s.invokeElem(xi2);
			} catch (NaAPIFailedException naf) {
				if(naf.getErrno()==9016)
					s_logger.warn("no map exists excpn 9016 caught in deletelun, continuing with delete");
			}

			//destroy lun
			NaElement xi = new NaElement("lun-destroy");
			xi.addNewChild("force","true");
			xi.addNewChild("path", lun.getPath()+lun.getLunName());
			s.invokeElem(xi);
			
			//destroy igroup
			NaElement xi1 = new NaElement("igroup-destroy");
			//xi1.addNewChild("force","true");
			xi1.addNewChild("initiator-group-name",lunName);
			s.invokeElem(xi1);
			
			_lunDao.remove(lun.getId());
			txn.commit();
		} catch(UnknownHostException uhe) {
			txn.rollback();
			s_logger.warn("Failed to delete lun", uhe);
			throw new ServerException("Failed to delete lun", uhe);
		} catch ( IOException ioe) {
			txn.rollback();
			s_logger.warn("Failed to delete lun", ioe);
			throw new ServerException("Failed to delete lun", ioe);
		}catch (NaAPIFailedException naf) {
			if(naf.getErrno() == 9017){//no such group exists excpn
				s_logger.warn("no such group exists excpn 9017 caught in deletelun, continuing with delete");
				_lunDao.remove(lun.getId());
				txn.commit();
			}else if(naf.getErrno() == 9029){//LUN maps for this initiator group exist
				s_logger.warn("LUN maps for this initiator group exist errno 9029 caught in deletelun, continuing with delete");
				_lunDao.remove(lun.getId());
				txn.commit();
			}else{
				txn.rollback();
				s_logger.warn("Failed to delete lun", naf);
				throw new ServerException("Failed to delete lun", naf);
			}

		} 
		catch (NaException nae) {
			txn.rollback();
			s_logger.warn("Failed to delete lun", nae);
			throw new ServerException("Failed to delete lun", nae);
		}
		finally{
			if (vol != null) {
				_volumeDao.releaseFromLockTable(vol.getId());
			}
			if (s != null)
				s.close();
		}

	}
	
	/**
	 * This method lists the luns on the netapp filer
	 * @param volId -- id of the containing volume
	 * @return -- list of netapp luns
	 * @throws NaException
	 * @throws IOException
	 */
    @Override
    public List<LunVO> listLunsOnFiler(String poolName)
	{
		if(s_logger.isDebugEnabled())
			s_logger.debug("Request --> listLunsOnFiler ");
		
    	List<LunVO> luns = new ArrayList<LunVO>();
    	
    	List<NetappVolumeVO> vols = _volumeDao.listVolumes(poolName);
    	
    	for(NetappVolumeVO vol : vols)
    	{
    		luns.addAll(_lunDao.listLunsByVolId(vol.getId()));
    	}
    
		if(s_logger.isDebugEnabled())
			s_logger.debug("Response --> listLunsOnFiler:success");
    	
    	return luns;
	}
	

	/**
	 * This method disassociates a lun from the igroup on the filer
	 * @param iGroup -- igroup name
	 * @param lunName -- lun name
	 */
    @Override
	public void disassociateLun(String iGroup, String lunName) throws ServerException, InvalidParameterValueException
	{
		NaElement xi;
		LunVO lun = _lunDao.findByName(lunName);
		
		if(lun == null)
			throw new InvalidParameterValueException("Cannot find LUN " + lunName);
		
		NetappVolumeVO vol = _volumeDao.findById(lun.getVolumeId());
		NaServer s = null;
		try {
			s = getServer(vol.getIpAddress(), vol.getUsername(), vol.getPassword());
			
			if(s_logger.isDebugEnabled())
				s_logger.debug("Request --> disassociateLun "+":serverIp:"+vol.getIpAddress());
			
			xi = new NaElement("igroup-remove");
			xi.addNewChild("force", "true");
			xi.addNewChild("initiator", iGroup);
			xi.addNewChild("initiator-group-name", lunName);		
			s.invokeElem(xi);
			
		} catch(UnknownHostException uhe) {
			throw new ServerException("Failed to disassociate lun", uhe);
		} catch ( IOException ioe) {
			throw new ServerException("Failed to disassociate lun", ioe);
		} catch (NaException nae) {
			throw new ServerException("Failed to disassociate lun", nae);
		} finally{
			if (s != null)
				s.close();
		}
		
	}
	
	/**
	 * This method associates a lun to a particular igroup
	 * @param iqn
	 * @param iGroup
	 * @param lunName
	 */
    @Override
	public String[] associateLun(String guestIqn, String lunName) throws ServerException, InvalidParameterValueException

	{
		NaElement xi2;

		//get lun id from path
		String[] splitLunName = lunName.split("-");
		String[] returnVal = new String[3];
		if(splitLunName.length != 2)
			throw new InvalidParameterValueException("The lun id is malformed");
		
		String lunIdStr = splitLunName[1]; 

		Long lId = new Long(lunIdStr);
		
		LunVO lun = _lunDao.findById(lId);
		
		if(lun == null)
			throw new InvalidParameterValueException("Cannot find LUN " + lunName);
		
		NetappVolumeVO vol = _volumeDao.findById(lun.getVolumeId());

		//assert(vol != null);
		
		returnVal[0] = lunIdStr;
		returnVal[1] = lun.getTargetIqn();
		returnVal[2] = vol.getIpAddress();
		
		NaServer s = null;
		
		try
		{
			s = getServer(vol.getIpAddress(), vol.getUsername(), vol.getPassword()); 
			
			if(s_logger.isDebugEnabled())
				s_logger.debug("Request --> associateLun "+":serverIp:"+vol.getIpAddress());
			
			//add iqn to the group
			xi2 = new NaElement("igroup-add");
			xi2.addNewChild("force", "true");
			xi2.addNewChild("initiator", guestIqn);
			xi2.addNewChild("initiator-group-name", lunName);		
			s.invokeElem(xi2);
						
			return returnVal;
		}  catch (UnknownHostException uhe) {
			s_logger.warn("Unable to associate LUN " , uhe);
			throw new ServerException("Unable to associate LUN", uhe);
		}catch (NaAPIFailedException naf){
			if(naf.getErrno() == 9008){ //initiator group already contains node				
				return returnVal;
			}			
			s_logger.warn("Unable to associate LUN " , naf);
			throw new ServerException("Unable to associate LUN", naf);
		}
		catch (NaException nae) {
			s_logger.warn("Unable to associate LUN " , nae);
			throw new ServerException("Unable to associate LUN", nae);
		} catch (IOException ioe) {
			s_logger.warn("Unable to associate LUN " , ioe);
			throw new ServerException("Unable to associate LUN", ioe);
		}
		finally{
			if (s != null)
				s.close();
		}
		
	}

	@Override
	public boolean configure(String name, Map<String, Object> params)
			throws ConfigurationException {

       _name = name;
       
       _netappAllocator = new NetappDefaultAllocatorImpl( this );

		return true;
	}

	@Override
	public String getName() {
		return _name;
	}

	@Override
	public boolean start() {
		return true;
	}

	@Override
	public boolean stop() {
		return true;
	}
	
}
