package liquibase.ext;

import com.google.common.collect.ImmutableSet;
import liquibase.database.structure.type.CharType;
import liquibase.database.structure.type.CustomType;
import liquibase.database.structure.type.DataType;
import liquibase.database.typeconversion.core.OracleTypeConverter;

import java.util.Set;

/**
 * Override the VARCHAR/2 and NVARCHAR/2 to use "CHAR"s not "BYTE"s
 */
@SuppressWarnings("unused")
public class CustomOracleTypeConverter extends OracleTypeConverter {

    @Override
    public int getPriority() {
        return Priority.PRIORITY_OVERRIDE;
    }

    /**
     * List of types to fors "CHAR" units on
     */
    private static Set<String> FORCE_CHARS = ImmutableSet.of("VARCHAR", "VARCHAR2", "NVARCHAR", "NVARCHAR2", "CHAR");

    /**
     * Check for types to force "CHAR" units on
     */
    @Override
    protected DataType getDataType(String columnTypeString, Boolean autoIncrement, String dataTypeName, String precision, String additionalInformation) {
        DataType returnTypeName = super.getDataType(columnTypeString, autoIncrement, dataTypeName, precision, additionalInformation);

        if (returnTypeName instanceof CustomType) {
            boolean returnTypeChanged = false;
            if (columnTypeString.toUpperCase().startsWith("CHARACTER")) {
                returnTypeName = new CharType();
                returnTypeChanged = true;
            }

            if (returnTypeChanged) {
                addPrecisionToType(precision, returnTypeName);
            }
        }

        if ((returnTypeName.getDataTypeName() != null) && FORCE_CHARS.contains(returnTypeName.getDataTypeName())) {
            returnTypeName.setUnit("CHAR");
        }

        return returnTypeName;
    }
}
