package cn.stylefeng.team.generator.core;

import cn.hutool.core.lang.Dict;
import cn.stylefeng.team.generator.api.CodeGeneratorApi;
import cn.stylefeng.team.generator.api.exception.GenerationException;
import cn.stylefeng.team.generator.api.exception.enums.GenerationExceptionEnum;
import cn.stylefeng.team.generator.api.pojo.generator.result.CommonGenerateResult;
import cn.stylefeng.team.generator.api.pojo.template.GeneratorTemplate;
import cn.stylefeng.team.generator.core.tag.FormIncludeTag;
import cn.stylefeng.team.generator.core.tag.FormLayoutTag;
import cn.stylefeng.team.generator.core.util.TemplateFormatUtil;
import org.beetl.core.Configuration;
import org.beetl.core.GroupTemplate;
import org.beetl.core.Template;
import org.beetl.core.resource.StringTemplateResourceLoader;
import org.springframework.stereotype.Service;

import java.io.IOException;
import java.util.Map;
import java.util.Properties;

@Service
public class BeetlCodeGenerator implements CodeGeneratorApi {

    private GroupTemplate groupTemplate;

    public BeetlCodeGenerator() {
        this.initGroupTemplate(null);
    }

    public BeetlCodeGenerator(Properties properties) {
        this.initGroupTemplate(properties);
    }

    @Override
    public String codeGenerate(String templateContent, Map<String, Object> metadata) {
        Template template = groupTemplate.getTemplate(templateContent);
        template.binding(metadata);
        return template.render();
    }

    @Override
    public CommonGenerateResult generateCodeGetResult(GeneratorTemplate generatorTemplate, String filePrefix, Dict metadata) {

        CommonGenerateResult commonGenerateResult = new CommonGenerateResult();

        String content = this.codeGenerate(generatorTemplate.getContent(), metadata);
        commonGenerateResult.setFileContent(content);

        String fileName = filePrefix + generatorTemplate.getFileSuffix();
        commonGenerateResult.setFileName(fileName);

        String filePath = generatorTemplate.getFolderPath();
        filePath = filePath + "/" + fileName;
        commonGenerateResult.setFilePath(filePath);

        return commonGenerateResult;
    }

    private void initGroupTemplate(Properties properties) {
        if (properties == null) {
            properties = new Properties();
            properties.put("RESOURCE.root", "");
            properties.put("DELIMITER_STATEMENT_START", "<%");
            properties.put("DELIMITER_STATEMENT_END", "%>");
            properties.put("HTML_TAG_FLAG", "##");
        }

        try {
            Configuration beetlConfiguration = new Configuration(properties);
            groupTemplate = new GroupTemplate(new StringTemplateResourceLoader(), beetlConfiguration);
            groupTemplate.registerFunctionPackage("tool", TemplateFormatUtil.class);
            groupTemplate.registerTag("formInclude", FormIncludeTag.class);
            groupTemplate.registerTag("formLayout", FormLayoutTag.class);
        } catch (IOException exception) {
            throw new GenerationException(GenerationExceptionEnum.TEMPLATE_INIT_ERROR, exception.getMessage());
        }
    }
}
