/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */
package org.apache.brooklyn.entity.proxy.nginx;

import static java.lang.String.format;

import java.util.Collection;

import org.apache.brooklyn.entity.proxy.ProxySslConfig;
import org.apache.brooklyn.util.text.Strings;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.google.common.collect.LinkedHashMultimap;
import com.google.common.collect.Multimap;

/**
 * Generates the {@code server.conf} configuration file using sensors on an {@link NginxController}.
 */
public class NginxDefaultConfigGenerator implements NginxConfigFileGenerator {

    private static final Logger LOG = LoggerFactory.getLogger(NginxDefaultConfigGenerator.class);

    public NginxDefaultConfigGenerator() { }

    @Override
    public String generateConfigFile(NginxDriver driver, NginxController nginx) {
        StringBuilder config = new StringBuilder();
        config.append("\n");
        config.append(format("pid %s;\n", driver.getPidFile()));
        config.append("events {\n");
        config.append("  worker_connections 8196;\n");
        config.append("}\n");
        config.append("http {\n");

        ProxySslConfig globalSslConfig = nginx.getSslConfig();

        if (nginx.isSsl()) {
            verifyConfig(globalSslConfig);
            appendSslConfig("global", config, "    ", globalSslConfig, true, true);
        }

        // If no servers, then defaults to returning 404
        // TODO Give nicer page back
        if (nginx.getDomain()!=null || nginx.getServerPoolAddresses() == null || nginx.getServerPoolAddresses().isEmpty()) {
            config.append("  server {\n");
            config.append(getCodeForServerConfig());
            config.append("    listen "+nginx.getPort()+";\n");
            config.append(getCodeFor404());
            config.append("  }\n");
        }

        // For basic round-robin across the server-pool
        if (nginx.getServerPoolAddresses() != null && nginx.getServerPoolAddresses().size() > 0) {
            config.append(format("  upstream "+nginx.getId()+" {\n"));
            if (nginx.isSticky()){
                config.append("    sticky;\n");
            }
            for (String address : nginx.getServerPoolAddresses()) {
                config.append("    server "+address+";\n");
            }
            config.append("  }\n");
            config.append("  server {\n");
            config.append(getCodeForServerConfig());
            config.append("    listen "+nginx.getPort()+";\n");
            if (nginx.getDomain()!=null)
                config.append("    server_name "+nginx.getDomain()+";\n");
            config.append("    location / {\n");
            config.append("      proxy_pass "+(globalSslConfig != null && globalSslConfig.getTargetIsSsl() ? "https" : "http")+"://"+nginx.getId()+";\n");
            config.append("    }\n");
            config.append("  }\n");
        }

        // For mapping by URL
        Iterable<UrlMapping> mappings = nginx.getUrlMappings();
        Multimap<String, UrlMapping> mappingsByDomain = LinkedHashMultimap.create();
        for (UrlMapping mapping : mappings) {
            Collection<String> addrs = mapping.getAttribute(UrlMapping.TARGET_ADDRESSES);
            if (addrs != null && addrs.size() > 0) {
                mappingsByDomain.put(mapping.getDomain(), mapping);
            }
        }

        for (UrlMapping um : mappings) {
            Collection<String> addrs = um.getAttribute(UrlMapping.TARGET_ADDRESSES);
            if (addrs != null && addrs.size() > 0) {
                config.append(format("  upstream "+um.getUniqueLabel()+" {\n"));
                if (nginx.isSticky()){
                    config.append("    sticky;\n");
                }
                for (String address: addrs) {
                    config.append("    server "+address+";\n");
                }
                config.append("  }\n");
            }
        }

        for (String domain : mappingsByDomain.keySet()) {
            config.append("  server {\n");
            config.append(getCodeForServerConfig());
            config.append("    listen "+nginx.getPort()+";\n");
            config.append("    server_name "+domain+";\n");
            boolean hasRoot = false;

            // set up SSL
            ProxySslConfig localSslConfig = null;
            for (UrlMapping mappingInDomain : mappingsByDomain.get(domain)) {
                ProxySslConfig sslConfig = mappingInDomain.getConfig(UrlMapping.SSL_CONFIG);
                if (sslConfig!=null) {
                    verifyConfig(sslConfig);
                    if (localSslConfig!=null) {
                        if (localSslConfig.equals(sslConfig)) {
                            //ignore identical config specified on multiple mappings
                        } else {
                            LOG.warn("{} mapping {} provides SSL config for {} when a different config had already been provided by another mapping, ignoring this one",
                                    new Object[] {this, mappingInDomain, domain});
                        }
                    } else if (globalSslConfig!=null) {
                        if (globalSslConfig.equals(sslConfig)) {
                            //ignore identical config specified on multiple mappings
                        } else {
                            LOG.warn("{} mapping {} provides SSL config for {} when a different config had been provided at root nginx scope, ignoring this one",
                                    new Object[] {this, mappingInDomain, domain});
                        }
                    } else {
                        //new config, is okay
                        localSslConfig = sslConfig;
                    }
                }
            }
            if (localSslConfig != null) {
                appendSslConfig(domain, config, "    ", localSslConfig, true, true);
            }

            for (UrlMapping mappingInDomain : mappingsByDomain.get(domain)) {
                // TODO Currently only supports "~" for regex. Could add support for other options,
                // such as "~*", "^~", literals, etc.
                boolean isRoot = mappingInDomain.getPath()==null || mappingInDomain.getPath().length()==0 || mappingInDomain.getPath().equals("/");
                if (isRoot && hasRoot) {
                    LOG.warn(""+this+" mapping "+mappingInDomain+" provides a duplicate / proxy, ignoring");
                } else {
                    hasRoot |= isRoot;
                    String location = isRoot ? "/" : "~ " + mappingInDomain.getPath();
                    config.append("    location "+location+" {\n");
                    Collection<UrlRewriteRule> rewrites = mappingInDomain.getConfig(UrlMapping.REWRITES);
                    if (rewrites != null && rewrites.size() > 0) {
                        for (UrlRewriteRule rule: rewrites) {
                            config.append("      rewrite \"^"+rule.getFrom()+"$\" \""+rule.getTo()+"\"");
                            if (rule.isBreak()) config.append(" break");
                            config.append(" ;\n");
                        }
                    }
                    config.append("      proxy_pass "+
                        (localSslConfig != null && localSslConfig.getTargetIsSsl() ? "https" :
                         (localSslConfig == null && globalSslConfig != null && globalSslConfig.getTargetIsSsl()) ? "https" :
                         "http")+
                        "://"+mappingInDomain.getUniqueLabel()+" ;\n");
                    config.append("    }\n");
                }
            }
            if (!hasRoot) {
                //provide a root block giving 404 if there isn't one for this server
                config.append("    location / { \n"+getCodeFor404()+"    }\n");
            }
            config.append("  }\n");
        }

        config.append("}\n");

        return config.toString();
    }

    protected String getCodeForServerConfig() {
        // See http://wiki.nginx.org/HttpProxyModule
        return ""+
            // this prevents nginx from reporting version number on error pages
            "    server_tokens off;\n"+

            // this prevents nginx from using the internal proxy_pass codename as Host header passed upstream.
            // Not using $host, as that causes integration test to fail with a "connection refused" testing
            // url-mappings, at URL "http://localhost:${port}/atC0" (with a trailing slash it does work).
            "    proxy_set_header Host $http_host;\n"+

            // following added, as recommended for wordpress in:
            // http://zeroturnaround.com/labs/wordpress-protips-go-with-a-clustered-approach/#!/
            "    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;\n"+
            "    proxy_set_header X-Real-IP $remote_addr;\n";
    }

    protected String getCodeFor404() {
        return "    return 404;\n";
    }

    protected void verifyConfig(ProxySslConfig proxySslConfig) {
          if(Strings.isEmpty(proxySslConfig.getCertificateDestination()) && Strings.isEmpty(proxySslConfig.getCertificateSourceUrl())){
            throw new IllegalStateException("ProxySslConfig can't have a null certificateDestination and null certificateSourceUrl. One or both need to be set");
        }
    }

    protected boolean appendSslConfig(String id, StringBuilder out, String prefix, ProxySslConfig ssl,
                                   boolean sslBlock, boolean certificateBlock) {
        if (ssl == null) return false;
        if (sslBlock) {
            out.append(prefix);
            out.append("ssl on;\n");
        }
        if (ssl.getReuseSessions()) {
            out.append(prefix);
            out.append("");
        }
        if (certificateBlock) {
            String cert;
            if (Strings.isEmpty(ssl.getCertificateDestination())) {
                cert = "" + id + ".crt";
            } else {
                cert = ssl.getCertificateDestination();
            }

            out.append(prefix);
            out.append("ssl_certificate " + cert + ";\n");

            String key;
            if (!Strings.isEmpty(ssl.getKeyDestination())) {
                key = ssl.getKeyDestination();
            } else if (!Strings.isEmpty(ssl.getKeySourceUrl())) {
                key = "" + id + ".key";
            } else {
                key = null;
            }

            if (key != null) {
                out.append(prefix);
                out.append("ssl_certificate_key " + key + ";\n");
            }

            out.append("ssl_protocols TLSv1 TLSv1.1 TLSv1.2;\n");
        }
        return true;
    }

    @Override
    public String toString(){
        return getClass().getName();
    }

}
