package org.twig;

import org.twig.exception.LoaderException;
import org.twig.loader.Loader;

import javax.xml.bind.DatatypeConverter;
import java.io.UnsupportedEncodingException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;

public class Environment {
    private Loader loader;
    private String templateBaseClass = "org.twig.template.BaseTemplate";

    public Environment() {
    }

    public Environment(Loader loader) {
        this.loader = loader;
    }

    /**
     * @see this#getTemplateClass For docs
     */
    public String getTemplateClass(String name) throws LoaderException {
        return this.getTemplateClass(name, 0);
    }

    /**
     * Gets the template class associated with the given string.
     *
     * The generated template class is based on the following parameters:
     *
     *  * The cache key for the given template
     *
     * @param name The template name to get the class name from
     * @param index Idk what this is yet
     * @return The class name
     * @throws LoaderException If the template does not exist
     */
    public String getTemplateClass(String name, Integer index) throws LoaderException {
        String key = this.getLoader().getCacheKey(name);

        return hashText(key).concat("_").concat(index.toString());
    }

    /**
     * Create a sha 256 hash from something
     * @param text The text to hash
     * @return The checksum
     */
    private String hashText(String text) {
        try {
            MessageDigest md = MessageDigest.getInstance("SHA-256");

            byte[] digest = md.digest(text.getBytes("UTF-8"));

            return DatatypeConverter.printHexBinary(digest).toLowerCase();
        } catch (UnsupportedEncodingException e) {
            // This'll never gonna happen
            throw new RuntimeException("Something impossible just happened");
        } catch (NoSuchAlgorithmException e) {
            // This'll never happen
            throw new RuntimeException("Something impossible just happened");
        }
    }

    /**
     * Get the template loader
     * @return
     */
    public Loader getLoader() {
        return loader;
    }

    /**
     * Set the template loader
     * @param loader
     */
    public Environment setLoader(Loader loader) {
        this.loader = loader;

        return this;
    }

    /**
     * Get the template base class name
     * @return The template base class
     */
    public String getTemplateBaseClass() {
        return templateBaseClass;
    }

    /**
     * Set the template base class name
     * @param templateBaseClass The template base class
     */
    public void setTemplateBaseClass(String templateBaseClass) {
        this.templateBaseClass = templateBaseClass;
    }
}

@@ -32,62 +32,220 @@
 wig.
-exception.LoaderException;%0Aimport org.twig.loader.Load
+compiler.ClassCompiler;%0Aimport org.twig.compiler.RuntimeTemplateCompiler;%0Aimport org.twig.exception.LoaderException;%0Aimport org.twig.loader.Loader;%0Aimport org.twig.syntax.Lexer;%0Aimport org.twig.syntax.parser.Pars
 er;%0A
@@ -496,25 +496,23 @@
 template
-BaseClass
+Package
  = %22org.
@@ -528,22 +528,320 @@
 late
-.BaseTemplate%22
+%22;%0A    private String templateBaseClass = templatePackage + %22.Template%22;%0A    private Lexer lexer = new Lexer();%0A    private Parser parser = new Parser();%0A    private ClassCompiler classCompiler = new ClassCompiler(this);%0A    private RuntimeTemplateCompiler runtimeTemplateCompiler = new RuntimeTemplateCompiler()
 ;%0A%0A 
@@ -2250,14 +2250,8 @@
 ver 
-gonna 
 happ
@@ -3223,11 +3223,996 @@
 s;%0A    %7D
+%0A%0A    /**%0A     * Set the template's package name (namespace)%0A     * @param templatePackage The package%0A     */%0A    public void setTemplatePackage(String templatePackage) %7B%0A        this.templatePackage = templatePackage;%0A    %7D%0A%0A    /**%0A     * Set the lexer%0A     * @param lexer The lexer%0A     */%0A    public void setLexer(Lexer lexer) %7B%0A        this.lexer = lexer;%0A    %7D%0A%0A    /**%0A     * Set the parser%0A     * @param parser The parser%0A     */%0A    public void setParser(Parser parser) %7B%0A        this.parser = parser;%0A    %7D%0A%0A    /**%0A     * Set the class compiler%0A     * @param classCompiler The class compiler%0A     */%0A    public void setClassCompiler(ClassCompiler classCompiler) %7B%0A        this.classCompiler = classCompiler;%0A    %7D%0A%0A    /**%0A     * Set the runtime template compiler%0A     * @param runtimeTemplateCompiler%0A     */%0A    public void setRuntimeTemplateCompiler(RuntimeTemplateCompiler runtimeTemplateCompiler) %7B%0A        this.runtimeTemplateCompiler = runtimeTemplateCompiler;%0A    %7D
 %0A%7D%0A

Add dependencies to the twig enviroment