package me.chyxion.tigon.service.support;

import lombok.Getter;
import lombok.Setter;
import java.util.Date;
import java.util.List;
import java.util.ArrayList;
import java.util.Collections;
import lombok.extern.slf4j.Slf4j;
import me.chyxion.tigon.model.M1;
import me.chyxion.tigon.model.BaseModel;
import me.chyxion.tigon.model.ViewModel;
import me.chyxion.tigon.mybatis.BaseMapper;
import me.chyxion.tigon.sequence.IdSequence;
import me.chyxion.tigon.service.BaseService;
import org.springframework.core.GenericTypeResolver;
import org.springframework.beans.factory.annotation.Autowired;

/**
 * @version 0.0.1
 * @since 0.0.1
 * @author Shaun Chyxion <br>
 * chyxion@163.com <br>
 * Nov 8, 2016 10:09:29 AM
 */
@Slf4j
@Getter
@Setter
public class BaseServiceSupport
    <PrimaryKey, Model extends BaseModel<PrimaryKey>,
        Mapper extends BaseMapper<PrimaryKey, Model>>
    implements BaseService<PrimaryKey, Model> {

    @Autowired
    protected Mapper mapper;
    @Autowired
    protected IdSequence idSeq;
    protected Class<PrimaryKey> idType;
    protected Class<Model> modelType;

    /**
     * constructor
     */
    @SuppressWarnings("unchecked")
    public BaseServiceSupport() {
        Class<?>[] clazzArr = 
            GenericTypeResolver.resolveTypeArguments(
                getClass(), 
            BaseServiceSupport.class);
        idType = (Class<PrimaryKey>) clazzArr[0];
        modelType = (Class<Model>) clazzArr[1];
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public ViewModel<Model> toViewModel(Model model) {
        ViewModel<Model> viewModel =
            new ViewModel<Model>(model);
        log.debug("Model [{}] To View Model.", model);
        processViewModel(viewModel, model);
        return viewModel;
    }

    /**
     * {@inheritDoc} 
     */
    @Override
    public List<ViewModel<Model>> toViewModel(List<Model> models) {
        List<ViewModel<Model>> viewModels = null;
        if (models != null && !models.isEmpty()) {
            viewModels = new ArrayList<ViewModel<Model>>(models.size());
            for (Model model : models) {
                viewModels.add(toViewModel(model));
            }
        }
        else {
            viewModels = Collections.emptyList();
        }
        return viewModels;
    }

    /**
     * @param model model
     * @param url url
     * @return url
     */
    protected String urlCacheClear(M1<PrimaryKey> model, String url) {
        Date dateUpdated = model.getDateUpdated();
        return dateUpdated != null ? 
            url + "?_d=" + dateUpdated.getTime() : url;
    }

    /**
     * @param viewModel view model
     * @param model model
     */
    protected void processViewModel(ViewModel<Model> viewModel, Model model) {
        // For Subclass Override
    }
}
