package com.atlassian.stash.internal.backup.liquibase;

import com.atlassian.stash.internal.backup.liquibase.xml.XmlEncoder;
import liquibase.change.ColumnConfig;

/**
 * Encapsulates the state relevant to parsing of a {@code <column>...</column>} tag.
 */
final class ColumnParsingContext {

    /** Stores the portion of the column value read so far */
    private final StringBuilder buffer;

    /** The name of the column being parsed */
    private final String columnName;

    /** The type of the column being parsed */
    private final ColumnSerialisationType columnSerialisationType;

    ColumnParsingContext(String columnName, ColumnSerialisationType columnSerialisationType) {
        this.columnName = columnName;
        this.columnSerialisationType = columnSerialisationType;
        this.buffer = new StringBuilder();
    }

    void append(char[] ch, int start, int len) {
        buffer.append(ch, start, len);
    }

    /**
     * Produces a {@link liquibase.change.ColumnConfig column config} the value of which is the decoded
     * contents of the internal buffer filled by calls to the {@link #append} method.
     *
     * @param xmlEncoder used to decode the buffer contents
     * @return a new column config
     */
    ColumnConfig asColumnConfig(XmlEncoder xmlEncoder) {
        ColumnConfig column = new ColumnConfig();
        column.setName(columnName);
        String decoded = xmlEncoder.decode(buffer.toString());
        switch (columnSerialisationType) {
            case BOOLEAN:
                column.setValueBoolean(Boolean.parseBoolean(decoded));
                break;
            case NUMERIC:
                column.setValueNumeric(decoded);
                break;
            case DATE:
                column.setValueDate(decoded);
                break;
            case BINARY:
                column.setValueComputed(new DecodeBase64Function(decoded));
                break;
            default:
                column.setValue(decoded);
                break;
        }
        return column;
    }

}

