/*
 * Click nbfs://nbhost/SystemFileSystem/Templates/Licenses/license-default.txt to change this license
 * Click nbfs://nbhost/SystemFileSystem/Templates/Classes/Class.java to edit this template
 */
package at.nieslony.arachne.tomcat;

import at.nieslony.arachne.auth.PreAuthSettings;
import at.nieslony.arachne.settings.Settings;
import at.nieslony.arachne.settings.SettingsException;
import java.io.FileWriter;
import java.io.IOException;
import java.io.StringWriter;
import java.util.Date;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

/**
 *
 * @author claas
 */
@Service
@Slf4j
public class TomcatService {

    private final String FN_ARACHNE_CONF = "arachne.conf";
    private final String FN_ARACHNE_PRE_AUTH_CONF = "arachne-preauth.conf.inc";

    @Value("${arachneConfigDir}")
    private String arachneConfigDir;

    @Autowired
    private Settings settings;

    public String getApacheConfigFileName() {
        return arachneConfigDir + "/" + FN_ARACHNE_CONF;
    }

    public void saveApacheConfig() {
        TomcatSettings tomcatSettings = settings.getSettings(TomcatSettings.class);
        PreAuthSettings preAuthSettings = settings.getSettings(PreAuthSettings.class);

        try {
            tomcatSettings.save(settings);
        } catch (SettingsException ex) {
            log.error("Cannot save tomcat settings: " + ex.getMessage());
        }

        String now = new Date().toString();
        StringWriter config = new StringWriter();
        config.write("# Generated by Arachne on %s\n\n".formatted(now));
        config.write("ProxyPass");
        config.write(" \"%s\" ".formatted(tomcatSettings.getAjpLocation()));
        config.write(" \"ajp://127.0.0.1:%d%s\""
                .formatted(
                        tomcatSettings.getAjpPort(),
                        tomcatSettings.getAjpLocation()));
        if (tomcatSettings.isEnableAjpSecret()) {
            config.write(" secret=" + tomcatSettings.getAjpSecret());
        }
        config.write("\n");
        if (preAuthSettings.isPreAuthtEnabled()
                && preAuthSettings.isWriteApachePreAuthConfig()) {
            config.write("""
                     <Location %1$s>
                         AuthType            GSSAPI
                         AuthName            "Arachne"
                         GssapiCredStore     keytab:%2$s
                         GssapiBasicAuth     On
                         GssapiUseSessions   On
                         Session             On
                         SessionCookieName   gssapi_session path=/arachne;httponly;secure;
                         Require             valid-user

                         RewriteEngine       on
                         RewriteRule         ^(.*) $1 [E=AJP_%3$s:%%{%3$s},UnsafeAllow3F]
                         RewriteCond         %%{ENV:%3$s} !^$
                     </Location>
                     """
                    .formatted(
                            tomcatSettings.getAjpLocation(),
                            preAuthSettings.getKeytabFile(),
                            preAuthSettings.getEnvironmentVariable()
                    )
            );
        }

        try (FileWriter writer = new FileWriter(getApacheConfigFileName())) {
            writer.write(config.toString());
        } catch (IOException ex) {
            log.error("Cannot write %s: %s".formatted(getApacheConfigFileName(), ex.getMessage()));
        }
    }
}
