package com.github.braisdom.objsql;

import com.github.braisdom.objsql.transition.ColumnTransition;

import java.sql.Statement;
import java.util.Optional;

/**
 * Describes the Java Bean which maps a row in the table, and behaviors
 * for Java Bean mapping.<br/>
 *
 * By default, a row of table will be adapted into an instance of Java Bean, if you need
 * different rule of mapping, you can implement it for querying and persistence.
 *
 * @see Query
 * @see Persistence
 * @see AbstractQuery#AbstractQuery(DomainModelDescriptor)
 * @see AbstractPersistence#AbstractPersistence(DomainModelDescriptor)
 *
 * @author braisdom
 */
public interface TableRowAdapter<T> {

    /**
     * Returns a table name which associates Java Bean
     * @return table name
     */
    String getTableName();

    /**
     * Returns a Java class which associates table
     * @return
     */
    Class getDomainModelClass();

    /**
     * Creates an instance of associated Java class
     * @return
     */
    T newInstance();

    /**
     * Set a primary key generated by database. Notice: not all databases support generated keys.
     * @param bean
     * @param primaryKeyValue
     *
     * @see Statement#getGeneratedKeys()
     */
    default void setGeneratedKey(T bean, Object primaryKeyValue) {
        throw new UnsupportedOperationException("The setGeneratedKey is unsupported");
    }

    /**
     * Returns field name by given column name
     * @param columnName
     * @return
     */
    String getFieldName(String columnName);

    default Optional<String> getFieldDefaultValue(String fieldName) {
        throw new UnsupportedOperationException("The getFieldDefaultValue is unsupported");
    }

    default boolean hasDefaultValue(String fieldName) {
        throw new UnsupportedOperationException("The hasDefaultValue is unsupported");
    }

    default FieldValue getFieldValue(Object bean, String fieldName) {
        throw new UnsupportedOperationException("The getFieldValue is unsupported");
    }

    default Class getFieldType(String fieldName) {
        throw new UnsupportedOperationException("The getFieldType is unsupported");
    }

    default boolean isTransitable(String fieldName) {
        throw new UnsupportedOperationException("The isTransitable is unsupported");
    }

    default ColumnTransition getColumnTransition(String fieldName) {
        throw new UnsupportedOperationException("The getColumnTransition is unsupported");
    }

    default void setFieldValue(T modelObject, String fieldName, Object fieldValue) {
        throw new UnsupportedOperationException("The setFieldValue is unsupported");
    }
}
