package me.chyxion.tigon.mybatis;

import org.w3c.dom.Element;
import org.w3c.dom.Document;
import lombok.extern.slf4j.Slf4j;
import me.chyxion.tigon.util.WordUtils;
import me.chyxion.tigon.model.BaseModel;
import org.apache.commons.lang3.StringUtils;
import org.springframework.core.annotation.AnnotationUtils;

/**
 * @author Shaun Chyxion <br>
 * chyxion@163.com <br>
 * Feb 21, 2017 17:42:03
 */
@Slf4j
public class TableXmlProcessor extends AbstractOnMissingCreateProcessor {

    /**
     * {@inheritDoc}
     */
    @Override
    protected String missingXPathExpression() {
        return "/mapper/sql[@id='table']";
    }

    /**
     * {@inheritDoc}
     */
    @Override
    protected Element elementToAppend(Class<BaseMapper<?, ?>> mapperClass, Document doc) {
        Element tableEl = doc.createElement("sql");
        tableEl.setAttribute("id", "table");
        Class<BaseModel<?>> modelClass = getModelClass(mapperClass);

        // find table from mapper annotation
        Table tableAnnotation =
            AnnotationUtils.findAnnotation(mapperClass, Table.class);
        if (tableAnnotation == null) {
            log.debug("No Mapper [{}] Table Annotation Found, Try To Find From Model Class.", mapperClass);
            // find table from model annotation
            tableAnnotation =
                AnnotationUtils.findAnnotation(modelClass, Table.class);
        }

        String tableName = null;
        if (tableAnnotation != null) {
            tableName = tableAnnotation.value();
            log.debug("Annotation Table Name [{}] Found.", tableName);
        }

        // convert model name to table name
        if (StringUtils.isBlank(tableName)) {
            final String modelName = modelClass.getSimpleName();
            tableName = WordUtils.convertCamelCase(modelName, "_")
                .toLowerCase();
            log.debug("Get Table Name [{}] From Model Class Name [{}]", tableName, modelName);
        }
        log.info("Mapper [{}] Table Name [{}] Found.", mapperClass, tableName);
        tableEl.setTextContent(tableName);
        return tableEl;
    }
}
