package com.atlassian.bitbucket.mesh.logback;

import ch.qos.logback.core.spi.ContextAwareBase;
import ch.qos.logback.core.spi.PropertyDefiner;

import java.io.File;

/**
 * Defines the directory where the system should store its logs. This is done using a {@link PropertyDefiner} so
 * it can fall back on environment variable if no system property is defined. If neither is defined, {@code null}
 * is returned and the property is not actually defined.
 */
public class LogDirPropertyDefiner extends ContextAwareBase implements PropertyDefiner {

    static final String ENV_KEY = "MESH_HOME";
    static final String PROP_KEY = "mesh.home";

    private final PropertyResolver resolver;

    @SuppressWarnings("unused") //Used by Logback via reflection
    public LogDirPropertyDefiner() {
        this(new PropertyResolver() {

            @Override
            public String getEnvironmentVariable(String name) {
                return System.getenv(name);
            }

            @Override
            public String getSystemProperty(String name) {
                return System.getProperty(name);
            }
        });
    }

    LogDirPropertyDefiner(PropertyResolver resolver) {
        this.resolver = resolver;
    }

    @Override
    public String getPropertyValue() {
        String home = resolver.getSystemProperty(PROP_KEY);
        if (home == null) {
            home = resolver.getEnvironmentVariable(ENV_KEY);
            if (home == null) {
                return null;
            }
        }

        return home + File.separator + "log";
    }

    /**
     * An abstraction over the {@link System#getenv} and {@link System#getProperty} accessors to simplify unit
     * testing (since environment variables can't be readily added/removed at runtime).
     */
    interface PropertyResolver {

        String getEnvironmentVariable(String name);

        String getSystemProperty(String name);
    }
}
