package net.crowmagnumb.database;


import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.builder.ToStringBuilder;


public class SqlColumn implements SqlComponent {
    private final String        _name;
    private final SqlColumnType _type;
    private SqlTable            _table;
    private final String        _alias;
    private String              _properName;
    private String              _constraints;

    //
    //    Used for char and varchars
    //
    private Integer _charMaxLength;

    private String _prefix = null;
    private String _suffix = null;


    public SqlColumn(final SqlTable table, final String name) {
        this(table, name, SqlColumnType.OTHER, null);
    }


    public SqlColumn(final SqlTable table, final String name, final String alias) {
        this(table, name, SqlColumnType.OTHER, alias);
    }

    public SqlColumn(final String name, final SqlColumnType type) {
        this(null, name, type, null);
    }

    public SqlColumn(final SqlTable table, final String name, final SqlColumnType type) {
        this(table, name, type, null);
    }

    public SqlColumn(final SqlTable table, final String name, final String properName, final SqlColumnType type) {
        this(table, name, type, null);

        _properName = properName;
    }

    public SqlColumn(final SqlTable table, final String name, final SqlColumnType type, final String alias) {
        _table = table;
        _name  = name;
        _type  = type;
        _alias = alias;
    }

    public SqlTable getTable() {
        return _table;
    }

    public void setTable( final SqlTable table) {
        _table = table;
    }

    public String getName() {
        return _name;
    }

    public SqlColumnType getType() {
        return _type;
    }

    public String getProperName() {
        if (_properName == null) {
            return _name;
        }

        return _properName;
    }

    public void setCharMaxLength(final Integer charMaxLength) {
        _charMaxLength = charMaxLength;
    }

    public Integer getCharMaxLength() {
        return _charMaxLength;
    }

    public void setConstraints(final String constraints) {
        _constraints = constraints;
    }

    public String getConstraints() {
        return _constraints;
    }

    /**
     *    The prefix and suffix are simply mechanisms to cheat
     *    in case you have an usual column (like a function
     *    call that you need to shoehorn into this structure.
     *    When the column is formatted for output the prefix
     *    and suffix are tacked on.
     *
     *    @param prefix value
     */
    public void setPrefix(final String prefix) {
        _prefix = prefix;
    }

    public String getPrefix() {
        return _prefix;
    }

    public void setSuffix(final String suffix) {
        _suffix = suffix;
    }

    public String formatValue(final String value) {
        if (_type == SqlColumnType.TEXT) {
            //
            // TODO: Fix this so that we can search on question marks if need be.
            // To fix a problem I had trying to use this to make parameterized queries I
            // check for a question mark and if so do not wrap quotes. I guess we
            // need to pass in that it is a parameterized query in which case we don't
            // even specify the value.
            //
            if (value == "?") {
                return "?";
            }
            return DbUtils.wrapQuotes(value);
        }

        return value;
    }

    public String getSqlReference() {
        String value;

        if (! StringUtils.isBlank(_alias)) {
            value = _alias;
        } else {
            value = getStandardSqlReference();
        }

        if (_prefix != null) {
            value = _prefix + value;
        }

        if (_suffix != null) {
            value += _suffix;
        }

        return value;
    }

    private String getStandardSqlReference() {
        if (_table == null) {
            return _name;
        }

        return DbUtils.buildDbRef(_table.getSqlReference(), _name);
    }

    @Override
    public void appendToSqlBuffer(final StringBuilder buffer) {
        buffer.append(getStandardSqlReference());

        if (! StringUtils.isBlank(_alias)) {
            buffer.append(" AS ").append(_alias);
        }
    }

    //========================================
    //
    //    Standard common methods
    //
    //========================================
    @Override
    public String toString() {
        return new ToStringBuilder(this).append("table", _table)
                                        .append("name", _name)
                                        .append("alias", _alias)
                                        .append("type", _type)
                                        .append("charMaxLength", _charMaxLength)
                                        .toString();
    }
}
