/*
 * Copyright 2010 JBoss Inc
 *
 * 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 org.drools.examples.decisiontable;

import org.drools.core.util.IoUtils;
import org.drools.decisiontable.ExternalSpreadsheetCompiler;
import org.drools.decisiontable.InputType;
import org.drools.decisiontable.SpreadsheetCompiler;
import org.drools.core.event.DebugAgendaEventListener;
import org.drools.core.event.DebugProcessEventListener;
import org.drools.core.io.impl.ByteArrayResource;
import org.kie.internal.KnowledgeBase;
import org.kie.internal.KnowledgeBaseFactory;
import org.kie.internal.builder.DecisionTableConfiguration;
import org.kie.internal.builder.DecisionTableInputType;
import org.kie.internal.builder.KnowledgeBuilder;
import org.kie.internal.builder.KnowledgeBuilderError;
import org.kie.internal.builder.KnowledgeBuilderErrors;
import org.kie.internal.builder.KnowledgeBuilderFactory;
import org.kie.internal.io.ResourceFactory;
import org.kie.api.event.rule.RuleRuntimeEventListener;
import org.kie.api.io.Resource;
import org.kie.api.io.ResourceType;
import org.kie.internal.runtime.StatefulKnowledgeSession;

import java.io.IOException;
import java.io.InputStream;
import java.util.Arrays;
import java.util.Iterator;

/**
 * This shows off a rule template where the data provider is a spreadsheet.
 * This example uses the same spreadsheet as the Decision table example ({@link PricingRuleDTExample})
 * so that you can see the difference between the two.
 * 
 * Note that even though they  use the same spreadsheet, this example is just
 * concerned with the data cells and does not use any of the Decision Table data.
 */
public class PricingRuleGroupingExample {

    public static void main(String[] args) {
        PricingRuleGroupingExample launcher = new PricingRuleGroupingExample();
        launcher.executeExample();
    }

    private long executeExample() {

        //BUILD THE KBASE
        //KnowledgeBase kbase = this.buildKBase();
    	KnowledgeBase kbase = this.buildDTable();

        //GET A KSESSION
        StatefulKnowledgeSession ksession = kbase.newStatefulKnowledgeSession();

        ksession.addEventListener( new DebugAgendaEventListener() );
                		
        //now create some test data
        Driver driver = new Driver();        
        
       // driver.setBusinessUnit("LICENCING");
        //driver.setLicenceClassCount(2);
        //driver.setAge(19);
        //driver.setPriorClaims(1);
        //driver.setLocationRiskProfile("LOW");
        
        driver.setBusinessUnit("LICENCING");
        driver.setLicenceClassCount(1);
        driver.setServiceType("Replacement");
        driver.setLicenceClass("AUCE-Auctioneer Employed");
        driver.setSector("AUCTIONEER AND CHATTEL AUCTIONEER");
        driver.setClassList(Arrays.asList("A"));
        //driver.setSector("SECURITY");
        
        
        //Policy policy = new Policy();
        //policy.setType("COMPREHENSIVE");
        
        ksession.insert(driver);
        //ksession.insert(policy);
        
        //ksession.setGlobal("policy", policy);

                
        ksession.fireAllRules();

        //System.out.println("BASE PRICE IS: " + policy.getBasePrice());
        //System.out.println("DISCOUNT IS: " + policy.getDiscountPercent());
        System.out.println("FEE IS: " + driver.getFeeId());


        ksession.dispose();

       //return policy.getBasePrice();
       return driver.getFeeId();

    }

    KnowledgeBase buildDTable(){
    	DecisionTableConfiguration dtableconfiguration =

    		    KnowledgeBuilderFactory.newDecisionTableConfiguration();

    		        dtableconfiguration.setInputType( DecisionTableInputType.XLS );


    		        KnowledgeBuilder kbuilder = KnowledgeBuilderFactory.newKnowledgeBuilder();


    		        Resource xlsRes = ResourceFactory.newClassPathResource( "FeePricing-grouping-error.xls",

    		                                                                getClass() );

    		            		        
    		        SpreadsheetCompiler spreadsheetCompiler = new SpreadsheetCompiler();
    		        String rules = spreadsheetCompiler.compile(this.getClass().getResourceAsStream("FeePricing-grouping-error.xls"), InputType.XLS);
    		        //String rules = spreadsheetCompiler.compile(this.getClass().getResourceAsStream("ExamplePolicyPricing.xls"), InputType.XLS);
    		        System.out.println(rules);
    		        
    		        kbuilder.add( xlsRes, ResourceType.DTABLE, dtableconfiguration );
    		        
    		        if( kbuilder.hasErrors() ){
    		            System.err.println( "### compilation errors ###" );
    		            KnowledgeBuilderErrors errors = kbuilder.getErrors();
    		            for( KnowledgeBuilderError err: errors ){
    		            System.err.println( err.toString() );
    		            }
    		            throw new IllegalStateException( "compile errors" );
    		        }
    		        
    		        //BUILD KBASE
    		        KnowledgeBase kbase = KnowledgeBaseFactory.newKnowledgeBase();
    		        kbase.addKnowledgePackages(kbuilder.getKnowledgePackages());
    		        
    		        
    		        return kbase;
    }
    /**
     * Creates a new kbase containing the rules generated from the xls file and
     * the templates.
     * @return
     * @throws IOException
     */
    private KnowledgeBase buildKBase() {
        //first we compile the decision table into a whole lot of rules.
        final ExternalSpreadsheetCompiler converter = new ExternalSpreadsheetCompiler();

        String basePricingDRL = null;
        String promotionalPricingDRL = null;
        String xlsPricing = null;
        try {
            //the data we are interested in starts at row 10, column 3
            basePricingDRL = converter.compile(getSpreadsheetStream(), getBasePricingRulesStream(), 10, 3);
            //the data we are interested in starts at row 30, column 3
            promotionalPricingDRL = converter.compile(getSpreadsheetStream(), getPromotionalPricingRulesStream(), 30, 3);
        	
        			
        } catch (IOException e) {
            throw new IllegalArgumentException("Invalid spreadsheet stream.", e);
        }

        //compile the drls
        KnowledgeBuilder kbuilder = KnowledgeBuilderFactory.newKnowledgeBuilder();
        kbuilder.add(new ByteArrayResource(basePricingDRL.getBytes(IoUtils.UTF8_CHARSET)), ResourceType.DRL);
        kbuilder.add(new ByteArrayResource(promotionalPricingDRL.getBytes(IoUtils.UTF8_CHARSET)), ResourceType.DRL);

        
        
        //compilation errors?
        if (kbuilder.hasErrors()) {
            System.out.println("Error compiling resources:");
            Iterator<KnowledgeBuilderError> errors = kbuilder.getErrors().iterator();
            while (errors.hasNext()) {
                System.out.println("\t" + errors.next().getMessage());
            }
            throw new IllegalStateException("Error compiling resources");
        }


        //Uncomment to see the base pricing rules
        //System.out.println(basePricingDRL);
        //Uncomment to see the promotional pricing rules
        //System.out.println(promotionalPricingDRL);

        //BUILD KBASE
        KnowledgeBase kbase = KnowledgeBaseFactory.newKnowledgeBase();
        kbase.addKnowledgePackages(kbuilder.getKnowledgePackages());

        return kbase;

    }

    private InputStream getSpreadsheetStream() throws IOException {
        return ResourceFactory.newClassPathResource("org/drools/examples/decisiontable/ExamplePolicyPricing.xls").getInputStream();
    }

    private InputStream getBasePricingRulesStream() throws IOException {
        return ResourceFactory.newClassPathResource("org/drools/examples/decisiontable/BasePricing.drt").getInputStream();
    }

    private InputStream getPromotionalPricingRulesStream() throws IOException {
        return ResourceFactory.newClassPathResource("org/drools/examples/decisiontable/PromotionalPricing.drt").getInputStream();
    }
}
