package wa.server.plugin.apache;

import wa.server.WAConstants;
import wa.server.plugin.WAConfigEntry;
import wa.server.plugin.WAServiceConfig;
import wa.server.util.ConfigFileUtil;
import zutil.db.DBConnection;
import zutil.db.bean.DBBean;
import zutil.db.bean.DBBean.DBTable;
import zutil.io.IOUtil;
import zutil.ui.Configurator;

import java.io.FileInputStream;
import java.io.IOException;
import java.io.PrintStream;
import java.util.ArrayList;
import java.util.List;


public class ApacheConfigVirtualHost implements WAServiceConfig{
    private static final String CONFIG_NAME = "Apache Virtual Host";
    private static final String APACHE_MAIN_CONFIG_FILE = "/apache2/apache2.conf";
    private static final String APACHE_SITE_AVAILABLE_PATH = "/apache2/site-available/";
    private static final String STATIC_PRE_CONF = "wa/server/plugin/apache/apache_default.config";

    private List<ApacheVirtualHostEntry> vhosts = new ArrayList<>();


    public ApacheConfigVirtualHost() throws Exception {
        DBConnection db = WAConstants.getDB();
        vhosts = DBBean.load(db, ApacheVirtualHostEntry.class);
    }

	@Override
	public String getName() {
		return CONFIG_NAME;
	}

    public WAConfigEntry createConfig(){
        return new ApacheVirtualHostEntry();
    }
    public void deleteConfig(int id){

    }


	@Override
	public void configure() throws Exception {
        // Update main configuration file
        ConfigFileUtil.writeBetweenBoundary(
                WAConstants.getConfigFile(APACHE_MAIN_CONFIG_FILE),
                "#",
                IOUtil.getContentAsString(
                        new FileInputStream(STATIC_PRE_CONF)));

        // Write Vhost configuration
        for(ApacheVirtualHostEntry vhost : vhosts){
            vhost.configure();
        }
	}

    @Override
    public List<? extends WAConfigEntry> getConfigData() {
        return vhosts;
    }
    @Override
    public Class<? extends WAConfigEntry> getConfigClass() {
        return ApacheVirtualHostEntry.class;
    }


    @DBTable(WAConstants.DB_TABLE_PREFIX + "_apache_vhost")
    public static class ApacheVirtualHostEntry extends WAConfigEntry {
        @Configurator.Configurable("Domain")
        protected String domain;
        protected transient String domain_old;
        @Configurator.Configurable("DocRoot")
        protected String path;
        @Configurator.Configurable("SSL")
        protected boolean ssl;



        public String getDomain() {
            return domain;
        }
        public void setDomain(String domain) {
            this.domain = domain;
        }
        public String getPath() {
            return path;
        }
        public void setPath(String path) {
            this.path = path;
        }
        public boolean isSSL() {
            return ssl;
        }
        public void setSSL(boolean ssl) {
            this.ssl = ssl;
        }



        public final void configure() throws IOException {
            if(domain != domain_old){ // Configuration file has changed name
                WAConstants.getConfigFile(APACHE_SITE_AVAILABLE_PATH+ domain_old).delete();
                domain_old = domain;
            }
            PrintStream out = new PrintStream(
                    WAConstants.getConfigFile(APACHE_SITE_AVAILABLE_PATH+ domain));

            writeConfiguration(out);
            out.close();
        }
        protected void writeConfiguration(PrintStream out){
            if(ssl){
                out.println("<VirtualHost *:80>");
                out.println("	ServerName "+ domain +":80");
                out.println("	RewriteEngine On");
                out.println("	RewriteCond  %{SERVER_PORT} !^443$");
                out.println("	RewriteRule  ^(.*)$ https://server$1 [L,R]");
                out.println("</VirtualHost>");
                out.println("<VirtualHost *:443>");
                out.println("	ServerName "+ domain +":443");
                out.println("	DocumentRoot  "+ path);
                out.println();
                out.println("	SSLEngine on");
                out.println("	SSLCertificateFile     "+ WAConstants.getConfigFile(WAConstants.WA_SSL_CERT));
                out.println("	SSLCertificateKeyFile  "+ WAConstants.getConfigFile(WAConstants.WA_SSL_KEY));
                out.println("</VirtualHost>");
                out.println("");
            }
            else {
                out.println("<VirtualHost *:80>");
                out.println("	ServerName "+ domain +":80");
                out.println("	DocumentRoot "+ path);
                out.println("</VirtualHost>");
                out.println("");
            }
        }
    }
}
