package blanco.db.expander.query;

import blanco.db.conf.BlancoDbSetting;
import blanco.db.conf.Logging;
import blanco.db.expander.implementor.BlancoDbImplementor;
import blanco.db.properties.GenerationProperties;
import blanco.db.util.BlancoDbObjectStorage;
import blanco.ig.expander.Scope;
import blanco.ig.expander.Value;
import blanco.ig.expander.implementor.Call;
import blanco.ig.expander.implementor.Receiver;
import blanco.ig.expander.implementor.Statement;
import blanco.ig.expander.implementor.StringLiteral;
import blanco.ig.expander.method.MethodExpander;

public class Finalize extends MethodExpander {

    private GenerationProperties _properties = null;

    private BlancoDbSetting _setting = null;

    public Finalize() {
        super("finalize");

        BlancoDbObjectStorage storage = BlancoDbObjectStorage.getInstance();
        _setting = storage.getSetting();
        _properties = storage.getGenerationProperties();
    }

    public void setupSignature() {
        setScope(Scope.PROTECTED);
        addException(Throwable.class);

        if (_properties.isGenerateJavaDoc()) {
            getJavaDoc().addLine("finalizeメソッド<br>");
            getJavaDoc().addLine("クローズ忘れのバグを検知することを目的とします。");
        }
    }

    public void implement() {
        BlancoDbImplementor i = new BlancoDbImplementor(getData());

        Receiver r = null;

        r = new Receiver("super", "finalize");
        i.addStatement(r);

        Value statement = getField("Statement");

        Statement s = new Statement(statement);
        s.join("!=", new Statement(Value.NULL));
        i.openIf(s);
        Value message = new Value(String.class, "message");
        i.declareByDefault(message);
        Call callClass = new Call("getClass");
        Call c = callClass.call("getName");
        c.join("+", new StringLiteral(" : close()メソッドによるリソースの開放が行われていません。"));
        i.assign(message, callClass);

        if (_setting.getLogging().equals(Logging.LOG4J)) {
            Value logger = getField("Logger");
            r = new Receiver(logger);
            c = r.call("debug");
            c.addArgument(message);
            i.addStatement(r);

        } else {
            r = new Receiver(System.class, "out");
            c = r.call("println");
            c.addArgument(message);
            i.addStatement(r);

        }
        i.closeIf();
    }
}