<commit_before>package com.camunda.consulting.dmn_excel_tester;

import java.io.File;
import java.text.MessageFormat;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import org.camunda.bpm.dmn.engine.DmnDecision;
import org.camunda.bpm.dmn.engine.DmnEngine;
import org.camunda.bpm.dmn.engine.DmnEngineConfiguration;
import org.camunda.bpm.model.dmn.Dmn;
import org.camunda.bpm.model.dmn.DmnModelInstance;
import org.docx4j.openpackaging.exceptions.Docx4JException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.xlsx4j.exceptions.Xlsx4jException;

import com.camunda.consulting.dmn_excel_tester.data.EvaluatedResult;
import com.camunda.consulting.dmn_excel_tester.logic.DmnEvaluator;
import com.camunda.consulting.dmn_excel_tester.logic.ExcelDmnValidator;
import com.camunda.consulting.dmn_excel_tester.logic.ExcelSheetReader;

import javafx.application.Application;
import javafx.concurrent.Task;
import javafx.event.ActionEvent;
import javafx.geometry.Insets;
import javafx.geometry.Pos;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.control.ProgressIndicator;
import javafx.scene.control.ScrollPane;
import javafx.scene.control.TextField;
import javafx.scene.layout.ColumnConstraints;
import javafx.scene.layout.GridPane;
import javafx.scene.layout.HBox;
import javafx.scene.layout.Priority;
import javafx.scene.layout.RowConstraints;
import javafx.scene.layout.VBox;
import javafx.scene.paint.Color;
import javafx.scene.text.Font;
import javafx.scene.text.FontWeight;
import javafx.scene.text.Text;
import javafx.scene.text.TextFlow;
import javafx.stage.FileChooser;
import javafx.stage.Stage;
import javafx.stage.FileChooser.ExtensionFilter;

public class DmnExcelTester extends Application {
  
  private static final Logger log = LoggerFactory.getLogger(DmnExcelTester.class);
  
  String excelSheetFilename;
  String dmnFileName;

  public static void main(String[] args) throws Docx4JException, Xlsx4jException {
    DmnExcelTester dmnExcelTester = new DmnExcelTester();
    dmnExcelTester.evaluateDecisionsFromExcelInput(args);
  }

  public void evaluateDecisionsFromExcelInput(String[] args) throws Docx4JException, Xlsx4jException {
    // handle the input args
    if (args.length == 0) {
      launch(args);
      System.exit(0);
    }
    
    if (args.length < 2) {
      printUsage();
    }
    
    String excelSheetFilename = args[1]; 
    String dmnFileName = args[0];
    
    if (excelSheetFilename == null || dmnFileName == null) {
      printUsage();
    }
    
    // create the decision
    System.out.println(MessageFormat.format("Test of DMN table ''{0}''\nwith values from Excel sheet ''{1}''\n", dmnFileName, excelSheetFilename));
    
    List<Map<String, Object>> expectationsMismatches = readAndEvaluateDecsions(excelSheetFilename, dmnFileName);
    
    System.out.println("Results:");
    System.out.println(formatResultsForGui(expectationsMismatches));
    // save the results in a new tab and mark the results 'green' or 'red'
  }

  public List<Map<String, Object>> readAndEvaluateDecsions(String excelSheetFilename, String dmnFileName) throws Docx4JException, Xlsx4jException {
    File dmnTableFile = new File(dmnFileName);
    DmnModelInstance dmnModelInstance = Dmn.readModelFromFile(dmnTableFile);
    
    // open the excel file
    File excelFile = new File(excelSheetFilename);
    
    // read the sheet
    ExcelSheetReader excelSheetReader = new ExcelSheetReader(excelFile);
    List<Map<String,Object>> dataFromExcel = excelSheetReader.getDataFromExcel();
    
    // validate the excel to decision
    ExcelDmnValidator excelDmnValidator = new ExcelDmnValidator(dataFromExcel, dmnModelInstance);
    List<String> validationResult = excelDmnValidator.validateMatchingExcelAndDmnModel();
    if (validationResult.size() > 0) {
      System.out.println("Excelsheet doesn't fit to the dmn table: ");
      System.out.println(validationResult.toString());
      System.exit(2);
    }
    
    // evaluate the decisions with values from the excel sheet
    DmnEngine dmnEngine = DmnEngineConfiguration.createDefaultDmnEngineConfiguration().buildEngine();
    List<DmnDecision> decisions = dmnEngine.parseDecisions(dmnModelInstance);
    DmnEvaluator dmnEvaluator = new DmnEvaluator(decisions, dataFromExcel);
    List<Map<String,Object>> expectationsMismatches = dmnEvaluator.evaluateAllExpectations();
    return expectationsMismatches;
  }

  public List<Text> formatResultsForGui(List<Map<String, Object>> expectationsMismatches) {
    List<Text> result = new ArrayList<Text>();
    int i = 0;
    for (Map<String, Object> mismatchLine : expectationsMismatches) {
      if (i != 0) {
        if (mismatchLine.isEmpty()) {
          Text correctLine = new Text(MessageFormat.format("Line {0}: correct \n\n", i));
          correctLine.setFill(Color.GREEN);
          result.add(correctLine);
        } else {
          StringBuilder errorLineBuilder = new StringBuilder();
          errorLineBuilder.append(MessageFormat.format("Line {0} with errors:\n", i));
          for (String key : mismatchLine.keySet()) {
            if (mismatchLine.get(key) instanceof EvaluatedResult) {
              EvaluatedResult evaluatedResult = (EvaluatedResult)mismatchLine.get(key);
              errorLineBuilder.append(MessageFormat.format("{0}: expected: ''{1}'', result: ''{2}''\n", 
                  key, 
                  evaluatedResult.getExpected(), 
                  evaluatedResult.getResult()));
            } else if (mismatchLine.get(key) instanceof String) {
              errorLineBuilder.append(mismatchLine.get(key));
            }
          }
          errorLineBuilder.append('\n');
          Text errorLine = new Text(errorLineBuilder.toString());
          errorLine.setFill(Color.RED);<commit_msg>add validation of matching column names<commit_after>package com.camunda.consulting.dmn_excel_tester;

import java.io.File;
import java.text.MessageFormat;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.camunda.bpm.dmn.engine.DmnDecision;
import org.camunda.bpm.dmn.engine.DmnEngine;
import org.camunda.bpm.dmn.engine.DmnEngineConfiguration;
import org.camunda.bpm.model.dmn.Dmn;
import org.camunda.bpm.model.dmn.DmnModelInstance;
import org.docx4j.openpackaging.exceptions.Docx4JException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.xlsx4j.exceptions.Xlsx4jException;

import com.camunda.consulting.dmn_excel_tester.data.EvaluatedResult;
import com.camunda.consulting.dmn_excel_tester.logic.DmnEvaluator;
import com.camunda.consulting.dmn_excel_tester.logic.DmnTablePreparer;
import com.camunda.consulting.dmn_excel_tester.logic.ExcelDmnValidator;
import com.camunda.consulting.dmn_excel_tester.logic.ExcelSheetReader;

import javafx.application.Application;
import javafx.concurrent.Task;
import javafx.event.ActionEvent;
import javafx.geometry.Insets;
import javafx.geometry.Pos;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.control.ProgressIndicator;
import javafx.scene.control.ScrollPane;
import javafx.scene.control.TextField;
import javafx.scene.layout.ColumnConstraints;
import javafx.scene.layout.GridPane;
import javafx.scene.layout.HBox;
import javafx.scene.layout.Priority;
import javafx.scene.layout.RowConstraints;
import javafx.scene.layout.VBox;
import javafx.scene.paint.Color;
import javafx.scene.text.Font;
import javafx.scene.text.FontWeight;
import javafx.scene.text.Text;
import javafx.scene.text.TextFlow;
import javafx.stage.FileChooser;
import javafx.stage.Stage;
import javafx.stage.FileChooser.ExtensionFilter;

public class DmnExcelTester extends Application {
  
  private static final Logger log = LoggerFactory.getLogger(DmnExcelTester.class);
  
  String excelSheetFilename;
  String dmnFileName;

  public static void main(String[] args) throws Docx4JException, Xlsx4jException {
    DmnExcelTester dmnExcelTester = new DmnExcelTester();
    dmnExcelTester.evaluateDecisionsFromExcelInput(args);
  }

  public void evaluateDecisionsFromExcelInput(String[] args) throws Docx4JException, Xlsx4jException {
    // handle the input args
    if (args.length == 0) {
      launch(args);
      System.exit(0);
    }
    
    if (args.length < 2) {
      printUsage();
    }
    
    String excelSheetFilename = args[1]; 
    String dmnFileName = args[0];
    
    if (excelSheetFilename == null || dmnFileName == null) {
      printUsage();
    }
    
    // create the decision
    System.out.println(MessageFormat.format("Test of DMN table ''{0}''\nwith values from Excel sheet ''{1}''\n", dmnFileName, excelSheetFilename));
    
    List<Map<String, Object>> expectationsMismatches = readAndEvaluateDecsions(excelSheetFilename, dmnFileName);
    
    System.out.println("Results:");
    System.out.println(formatResultsForGui(expectationsMismatches));
    // save the results in a new tab and mark the results 'green' or 'red'
  }

  public List<Map<String, Object>> readAndEvaluateDecsions(String excelSheetFilename, String dmnFileName) throws Docx4JException, Xlsx4jException {
    File dmnTableFile = new File(dmnFileName);
    DmnModelInstance dmnModelInstance = Dmn.readModelFromFile(dmnTableFile);
    DmnTablePreparer dmnTablePreparer = new DmnTablePreparer(dmnModelInstance);
    DmnModelInstance preparedTable = dmnTablePreparer.prepareTable();
    
    // open the excel file
    File excelFile = new File(excelSheetFilename);
    
    // read the sheet
    ExcelSheetReader excelSheetReader = new ExcelSheetReader(excelFile);
    List<Map<String,Object>> dataFromExcel = excelSheetReader.getDataFromExcel();
    
    // validate the excel to decision
    ExcelDmnValidator excelDmnValidator = new ExcelDmnValidator(dataFromExcel, preparedTable);
    List<Map<String,Object>> expectationsMismatches = new ArrayList<Map<String, Object>>();
    List<String> validationResult = excelDmnValidator.validateMatchingExcelAndDmnModel();
    if (validationResult.size() > 0) {
      expectationsMismatches.add(new HashMap<>());
      HashMap<String, Object> validatonErrorMessage = new HashMap<>();
      validatonErrorMessage.put("error:", "Excelsheet doesn't fit to the dmn table: ");
      validatonErrorMessage.put("details:", validationResult.toString());
      expectationsMismatches.add(validatonErrorMessage);
    } else {    
      // evaluate the decisions with values from the excel sheet
      DmnEngine dmnEngine = DmnEngineConfiguration.createDefaultDmnEngineConfiguration().buildEngine();
      List<DmnDecision> decisions = dmnEngine.parseDecisions(dmnModelInstance);
      DmnEvaluator dmnEvaluator = new DmnEvaluator(decisions, dataFromExcel);
      expectationsMismatches = dmnEvaluator.evaluateAllExpectations();
    }
    return expectationsMismatches;
  }

  public List<Text> formatResultsForGui(List<Map<String, Object>> expectationsMismatches) {
    List<Text> result = new ArrayList<Text>();
    int i = 0;
    for (Map<String, Object> mismatchLine : expectationsMismatches) {
      if (i != 0) {
        if (mismatchLine.isEmpty()) {
          Text correctLine = new Text(MessageFormat.format("Line {0}: correct \n\n", i));
          correctLine.setFill(Color.GREEN);
          result.add(correctLine);
        } else {
          StringBuilder errorLineBuilder = new StringBuilder();
          errorLineBuilder.append(MessageFormat.format("Line {0} with errors:\n", i));
          for (String key : mismatchLine.keySet()) {
            if (mismatchLine.get(key) instanceof EvaluatedResult) {
              EvaluatedResult evaluatedResult = (EvaluatedResult)mismatchLine.get(key);
              errorLineBuilder.append(MessageFormat.format("{0}: expected: ''{1}'', result: ''{2}''\n", 
                  key, 
                  evaluatedResult.getExpected(), 
                  evaluatedResult.getResult()));
            } else if (mismatchLine.get(key) instanceof String) {
              errorLineBuilder.append(mismatchLine.get(key));
            }
          }
          errorLineBuilder.append('\n');
          Text errorLine = new Text(errorLineBuilder.toString());
          errorLine.setFill(Color.RED);
{'fraction_non_alphanumeric': 0.10354356306892068, 'fraction_numerical': 0.004470091027308193, 'mean_word_length': 4.172341319882303, 'pattern_counts': {'":': 0, '<': 42, '<?xml version=': 0, '>': 42, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2897679', 'n_tokens_mistral': 3827, 'n_tokens_neox': 3700, 'n_words': 713}