/*
 * Copyright © 2017 by Data Virtuality GmbH
 */
package org.teiid.translator.jdbc;

import org.teiid.language.ColumnReference;
import org.teiid.language.Literal;
import org.teiid.metadata.Column;
import org.teiid.translator.TranslatorException;

import java.util.Iterator;
import java.util.List;


/**
 * @author Roman Pedchenko
 * @date 2017.06.21
 */
public interface InsertRowGeneratorIntf {
    String getValueStringDelimiter();

    String valueToString(ColumnReference colRef, Object value, String delimiter) throws TranslatorException;

    String getValueStringNull();

    java.util.Date get10kMinusOneDate();

    class Util {
        public static String generateValueString(InsertRowGeneratorIntf gen, JDBCExecutionFactory ef, List<Column> tableColumns, List<ColumnReference> columns, List<?> values) throws TranslatorException {
            StringBuilder result = new StringBuilder();
            for (Iterator<Column> it = tableColumns.iterator(); it.hasNext(); ) {
                Column tableCol = it.next();
                ColumnReference actualCol = null;
                int colIndex = 0;
                for (Iterator<ColumnReference> it1 = columns.iterator(); it1.hasNext(); colIndex++) {
                    ColumnReference col = it1.next();
                    if (tableCol.getPosition() == col.getMetadataObject().getPosition()) {
                        actualCol = col;
                        break;
                    }
                }
                genSingleValue(gen, ef, values, actualCol, colIndex, it.hasNext(), result);
            }
            result.append("\n");
            return result.toString();
        }

        public static String generateProjectedValueString(InsertRowGeneratorIntf gen, JDBCExecutionFactory ef, List<ColumnReference> columns, List<?> values) throws TranslatorException {
            StringBuilder result = new StringBuilder();
            int colIndex = 0;
            for (Iterator<ColumnReference> it = columns.iterator(); it.hasNext(); colIndex++) {
                ColumnReference actualCol = it.next();
                genSingleValue(gen, ef, values, actualCol, colIndex, it.hasNext(), result);
            }
            result.append("\n");
            return result.toString();
        }

        private static void genSingleValue(InsertRowGeneratorIntf gen, JDBCExecutionFactory ef, List<?> values, ColumnReference actualCol, int colIndex, boolean hasNext, StringBuilder result) throws TranslatorException {
            if (actualCol == null)
                result.append(gen.getValueStringNull());
            else {
                Object value = values.get(colIndex);
                if (value instanceof Literal)
                    value = ((Literal) value).getValue();
                if (java.util.Date.class.isAssignableFrom(actualCol.getType()) && value != null) {
                    java.util.Date date = (java.util.Date) value;
                    if (date.after(gen.get10kMinusOneDate()))
                        value = null;
                }
                if (value == null) {
                    result.append(gen.getValueStringNull());
                } else {
                    if (ef != null) {
                        if (Double.class.isAssignableFrom(value.getClass()))
                            value = ef.pretranslateDouble(value);
                        else if (Float.class.isAssignableFrom(value.getClass()))
                            value = ef.pretranslateFloat(value);
                    }
                    String renderedVal = gen.valueToString(actualCol, value, gen.getValueStringDelimiter());
                    if (renderedVal == null)
                        result.append(gen.getValueStringNull());
                    else
                        result.append(renderedVal);
                }
            }
            if (hasNext)
                result.append(",");
        }
    }
}
