import java.io.File;
import java.io.IOException;
import java.io.Serializable;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.geotools.arcsde.ArcSDEDataStoreFactory;
import org.geotools.data.DataStore;
import org.geotools.data.DataUtilities;
import org.geotools.data.DefaultTransaction;
import org.geotools.data.FeatureStore;
import org.geotools.data.Transaction;
import org.geotools.data.shapefile.ShapefileDataStore;
import org.geotools.feature.FeatureIterator;
import org.geotools.feature.FeatureTypes;
import org.geotools.feature.simple.SimpleFeatureBuilder;
import org.geotools.jdbc.JDBCDataStoreFactory;
import org.geotools.referencing.CRS;
import org.opengis.feature.simple.SimpleFeature;
import org.opengis.feature.simple.SimpleFeatureType;
import org.opengis.feature.type.AttributeDescriptor;
import org.opengis.filter.Filter;
import org.opengis.referencing.crs.CoordinateReferenceSystem;


public class SDEImporter {

    public static void main(String[] args) throws Exception {
        String path = "/home/aaime/devel/gisData/scadden/seismic.shp";
        CoordinateReferenceSystem targetCRS = CRS.decode("EPSG:4326");
        ShapefileDataStore shp = new ShapefileDataStore(new File(path).toURL());
        
        Map<String, Serializable> params = new HashMap<String, Serializable>();
        params.put(ArcSDEDataStoreFactory.USER_PARAM.key, "sde");
        params.put(ArcSDEDataStoreFactory.PASSWORD_PARAM.key, "postgis");
        params.put(ArcSDEDataStoreFactory.SERVER_PARAM.key, "192.168.2.2");
        params.put(ArcSDEDataStoreFactory.PORT_PARAM.key, (Serializable) ArcSDEDataStoreFactory.PORT_PARAM.sample);
        // params.put(ArcSDEDataStoreFactory.INSTANCE_PARAM.key, "xe");
        params.put(ArcSDEDataStoreFactory.DBTYPE_PARAM.key, (Serializable) ArcSDEDataStoreFactory.DBTYPE_PARAM.sample);
        params.put(ArcSDEDataStoreFactory.MIN_CONNECTIONS_PARAM.key, 2);
        params.put(ArcSDEDataStoreFactory.MIN_CONNECTIONS_PARAM.key, 6);
        params.put(ArcSDEDataStoreFactory.TIMEOUT_PARAM.key, 500);
        params.put(ArcSDEDataStoreFactory.ALLOW_NON_SPATIAL_PARAM.key, false);
        
        DataStore oracle = new ArcSDEDataStoreFactory().createDataStore(params);
        if(oracle != null && oracle.getTypeNames() != null)
            System.out.println("SDE connected");
        
        List<String> typeNames = Arrays.asList(oracle.getTypeNames());
        System.out.println("Available types: " + typeNames);
        for (String name : typeNames) {
            System.out.println(name);
            try {
                SimpleFeatureType schema = oracle.getSchema(name);
                System.out.println(schema);
                System.out.println(schema.getGeometryDescriptor());
            } catch(Exception e) {
                System.out.println(e.getMessage());
            }
        }
        
        
        String targetType = "SDE." + shp.getSchema().getTypeName();
        if(!typeNames.contains(targetType))
            oracle.createSchema(FeatureTypes.transform(shp.getSchema(), targetCRS));
        System.out.println("Schema created");
        
        FeatureStore oraStore = (FeatureStore) oracle.getFeatureSource(targetType);
        oraStore.removeFeatures(Filter.INCLUDE);
        
        SimpleFeatureType targetSchema = (SimpleFeatureType) oraStore.getSchema();
        SimpleFeatureBuilder builder = new SimpleFeatureBuilder(targetSchema);
        
        FeatureIterator fi = shp.getFeatureSource().getFeatures().features();
        SimpleFeatureType sourceSchema = shp.getSchema();
        
        Transaction t = new DefaultTransaction();
        oraStore.setTransaction(t);
        while(fi.hasNext()) {
            SimpleFeature source = (SimpleFeature) fi.next();
        
            for(AttributeDescriptor ad : sourceSchema.getAttributeDescriptors()) {
                String attribute = ad.getLocalName();
                builder.set(attribute.toUpperCase(), source.getAttribute(attribute));
            }
            
            oraStore.addFeatures(DataUtilities.collection(builder.buildFeature(null)));
        }
        t.commit();
        t.close();
        
    }
}
