/*
 * 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.dns.geoscaling;

import java.text.SimpleDateFormat;
import java.util.Collection;
import java.util.Date;
import java.util.Iterator;
import java.util.TimeZone;

import org.apache.brooklyn.core.location.geo.HostGeoInfo;
import org.apache.brooklyn.util.core.ResourceUtils;
import org.apache.brooklyn.util.javalang.JavaClassNames;
import org.apache.brooklyn.util.os.Os;
import org.apache.brooklyn.util.text.Strings;

public class GeoscalingScriptGenerator {
    
    private static final String PHP_SCRIPT_TEMPLATE_RESOURCE = JavaClassNames.resolveClasspathUrl(GeoscalingScriptGenerator.class, "template.php");
    private static final String HOSTS_DECLARATIONS_MARKER = "/* HOST DECLARATIONS TO BE SUBSTITUTED HERE */";
    private static final String DATESTAMP_MARKER = "DATESTAMP";

    
    public static String generateScriptString(Collection<HostGeoInfo> hosts) {
        return generateScriptString(new Date(), hosts);
    }
    
    public static String generateScriptString(Date generationTime, Collection<HostGeoInfo> hosts) {
        String template = ResourceUtils.create(GeoscalingScriptGenerator.class).getResourceAsString(PHP_SCRIPT_TEMPLATE_RESOURCE);
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss 'UTC'");
        sdf.setTimeZone(TimeZone.getTimeZone("UTC"));
        String datestamp = sdf.format(generationTime);
        String declarations = getHostsDeclaration(hosts);
        return template
            .replaceAll(DATESTAMP_MARKER, datestamp)
            .replace(HOSTS_DECLARATIONS_MARKER, declarations);
    }
    
    private static String getHostsDeclaration(Collection<HostGeoInfo> hosts) {
        StringBuffer sb = new StringBuffer();
        sb.append("$hosts = array(\n");
        Iterator<HostGeoInfo> iServer = hosts.iterator();
        while (iServer.hasNext()) {
            HostGeoInfo server = iServer.next();
            sb.append("    array('name'      => '").append(escape(server.displayName)).append("',\n");
            sb.append("          'latitude'  => ").append(server.latitude).append(",\n");
            sb.append("          'longitude' => ").append(server.longitude).append(",\n");
            sb.append("          'ip'        => '").append(escape(server.address)).append("')");
            if (iServer.hasNext()) sb.append(",\n");
            sb.append("\n");
        }
        sb.append(");").append("\n");
        return sb.toString();
    }
    
    private static String escape(String txt) {
        txt = Strings.replaceAllNonRegex(txt, "\\", "\\\\");
        txt = Strings.replaceAllNonRegex(txt, "'", "\\'");
        txt = Strings.replaceAllNonRegex(txt, "\"", "\\\"'");
        return txt;
    }
    
}
