/*
 * 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.catalina.ant;

import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;

import org.apache.tools.ant.BuildException;

/**
 * Ant task that implements the <code>/status</code> command, supported by the mod_jk status (1.2.9) application.
 *
 * @author Peter Rossbach
 *
 * @since 5.5.9
 */
public class JKStatusUpdateTask extends AbstractCatalinaTask {

    private String worker = "lb";

    private String workerType = "lb";

    private int internalid = 0;

    private Integer lbRetries;

    private Integer lbRecovertime;

    private Boolean lbStickySession = Boolean.TRUE;

    private Boolean lbForceSession = Boolean.FALSE;

    private Integer workerLoadFactor;

    private String workerRedirect;

    private String workerClusterDomain;

    private Boolean workerDisabled = Boolean.FALSE;

    private Boolean workerStopped = Boolean.FALSE;

    private boolean isLBMode = true;

    private String workerLb;

    /**
     *
     */
    public JKStatusUpdateTask() {
        super();
        setUrl("http://localhost/status");
    }

    /**
     * @return Returns the internalid.
     */
    public int getInternalid() {
        return internalid;
    }

    /**
     * @param internalid The internalid to set.
     */
    public void setInternalid(int internalid) {
        this.internalid = internalid;
    }

    /**
     * @return Returns the lbForceSession.
     */
    public Boolean getLbForceSession() {
        return lbForceSession;
    }

    /**
     * @param lbForceSession The lbForceSession to set.
     */
    public void setLbForceSession(Boolean lbForceSession) {
        this.lbForceSession = lbForceSession;
    }

    /**
     * @return Returns the lbRecovertime.
     */
    public Integer getLbRecovertime() {
        return lbRecovertime;
    }

    /**
     * @param lbRecovertime The lbRecovertime to set.
     */
    public void setLbRecovertime(Integer lbRecovertime) {
        this.lbRecovertime = lbRecovertime;
    }

    /**
     * @return Returns the lbRetries.
     */
    public Integer getLbRetries() {
        return lbRetries;
    }

    /**
     * @param lbRetries The lbRetries to set.
     */
    public void setLbRetries(Integer lbRetries) {
        this.lbRetries = lbRetries;
    }

    /**
     * @return Returns the lbStickySession.
     */
    public Boolean getLbStickySession() {
        return lbStickySession;
    }

    /**
     * @param lbStickySession The lbStickySession to set.
     */
    public void setLbStickySession(Boolean lbStickySession) {
        this.lbStickySession = lbStickySession;
    }

    /**
     * @return Returns the worker.
     */
    public String getWorker() {
        return worker;
    }

    /**
     * @param worker The worker to set.
     */
    public void setWorker(String worker) {
        this.worker = worker;
    }

    /**
     * @return Returns the workerType.
     */
    public String getWorkerType() {
        return workerType;
    }

    /**
     * @param workerType The workerType to set.
     */
    public void setWorkerType(String workerType) {
        this.workerType = workerType;
    }

    /**
     * @return Returns the workerLb.
     */
    public String getWorkerLb() {
        return workerLb;
    }

    /**
     * @param workerLb The workerLb to set.
     */
    public void setWorkerLb(String workerLb) {
        this.workerLb = workerLb;
    }

    /**
     * @return Returns the workerClusterDomain.
     */
    public String getWorkerClusterDomain() {
        return workerClusterDomain;
    }

    /**
     * @param workerClusterDomain The workerClusterDomain to set.
     */
    public void setWorkerClusterDomain(String workerClusterDomain) {
        this.workerClusterDomain = workerClusterDomain;
    }

    /**
     * @return Returns the workerDisabled.
     */
    public Boolean getWorkerDisabled() {
        return workerDisabled;
    }

    /**
     * @param workerDisabled The workerDisabled to set.
     */
    public void setWorkerDisabled(Boolean workerDisabled) {
        this.workerDisabled = workerDisabled;
    }

    /**
     * @return Returns the workerStopped.
     */
    public Boolean getWorkerStopped() {
        return workerStopped;
    }

    /**
     * @param workerStopped The workerStopped to set.
     */
    public void setWorkerStopped(Boolean workerStopped) {
        this.workerStopped = workerStopped;
    }

    /**
     * @return Returns the workerLoadFactor.
     */
    public Integer getWorkerLoadFactor() {
        return workerLoadFactor;
    }

    /**
     * @param workerLoadFactor The workerLoadFactor to set.
     */
    public void setWorkerLoadFactor(Integer workerLoadFactor) {
        this.workerLoadFactor = workerLoadFactor;
    }

    /**
     * @return Returns the workerRedirect.
     */
    public String getWorkerRedirect() {
        return workerRedirect;
    }

    /**
     * @param workerRedirect The workerRedirect to set.
     */
    public void setWorkerRedirect(String workerRedirect) {
        this.workerRedirect = workerRedirect;
    }

    /**
     * Execute the requested operation.
     *
     * @exception BuildException if an error occurs
     */
    @Override
    public void execute() throws BuildException {

        super.execute();
        checkParameter();
        StringBuilder sb = createLink();
        execute(sb.toString(), null, null, -1);

    }

    /**
     * Create JkStatus link
     * <ul>
     * <li><b>load balance example: </b>http://localhost/status?cmd=update&mime=txt&w=lb&lf=false&ls=true</li>
     * <li><b>worker example: </b>http://localhost/status?cmd=update&mime=txt&w=node1&l=lb&wf=1&wd=false&ws=false</li>
     * </ul>
     *
     * @return create jkstatus link
     */
    private StringBuilder createLink() {
        // Building URL
        StringBuilder sb = new StringBuilder();
        try {
            sb.append("?cmd=update&mime=txt");
            sb.append("&w=");
            sb.append(URLEncoder.encode(worker, getCharset()));

            if (isLBMode) {
                // http://localhost/status?cmd=update&mime=txt&w=lb&lf=false&ls=true
                if ((lbRetries != null)) { // > 0
                    sb.append("&lr=");
                    sb.append(lbRetries);
                }
                if ((lbRecovertime != null)) { // > 59
                    sb.append("&lt=");
                    sb.append(lbRecovertime);
                }
                if ((lbStickySession != null)) {
                    sb.append("&ls=");
                    sb.append(lbStickySession);
                }
                if ((lbForceSession != null)) {
                    sb.append("&lf=");
                    sb.append(lbForceSession);
                }
            } else {
                // http://localhost/status?cmd=update&mime=txt&w=node1&l=lb&wf=1&wd=false&ws=false
                if ((workerLb != null)) { // must be configured
                    sb.append("&l=");
                    sb.append(URLEncoder.encode(workerLb, getCharset()));
                }
                if ((workerLoadFactor != null)) { // >= 1
                    sb.append("&wf=");
                    sb.append(workerLoadFactor);
                }
                if ((workerDisabled != null)) {
                    sb.append("&wd=");
                    sb.append(workerDisabled);
                }
                if ((workerStopped != null)) {
                    sb.append("&ws=");
                    sb.append(workerStopped);
                }
                if ((workerRedirect != null)) { // other worker conrecte lb's
                    sb.append("&wr=");
                }
                if ((workerClusterDomain != null)) {
                    sb.append("&wc=");
                    sb.append(URLEncoder.encode(workerClusterDomain, getCharset()));
                }
            }

        } catch (UnsupportedEncodingException e) {
            throw new BuildException("Invalid 'charset' attribute: " + getCharset());
        }
        return sb;
    }

    /**
     * check correct lb and worker parameter
     */
    protected void checkParameter() {
        if (worker == null) {
            throw new BuildException("Must specify 'worker' attribute");
        }
        if (workerType == null) {
            throw new BuildException("Must specify 'workerType' attribute");
        }
        if ("lb".equals(workerType)) {
            if (lbRecovertime == null && lbRetries == null) {
                throw new BuildException(
                        "Must specify at a lb worker either 'lbRecovertime' or" + "'lbRetries' attribute");
            }
            if (lbStickySession == null || lbForceSession == null) {
                throw new BuildException(
                        "Must specify at a lb worker either" + "'lbStickySession' and 'lbForceSession' attribute");
            }
            if (null != lbRecovertime && 60 < lbRecovertime.intValue()) {
                throw new BuildException("The 'lbRecovertime' must be greater than 59");
            }
            if (null != lbRetries && 1 < lbRetries.intValue()) {
                throw new BuildException("The 'lbRetries' must be greater than 1");
            }
            isLBMode = true;
        } else if ("worker".equals(workerType)) {
            if (workerDisabled == null) {
                throw new BuildException("Must specify at a node worker 'workerDisabled' attribute");
            }
            if (workerStopped == null) {
                throw new BuildException("Must specify at a node worker 'workerStopped' attribute");
            }
            if (workerLoadFactor == null) {
                throw new BuildException("Must specify at a node worker 'workerLoadFactor' attribute");
            }
            if (workerClusterDomain == null) {
                throw new BuildException("Must specify at a node worker 'workerClusterDomain' attribute");
            }
            if (workerRedirect == null) {
                throw new BuildException("Must specify at a node worker 'workerRedirect' attribute");
            }
            if (workerLb == null) {
                throw new BuildException("Must specify 'workerLb' attribute");
            }
            if (workerLoadFactor.intValue() < 1) {
                throw new BuildException("The 'workerLoadFactor' must be greater or equal 1");
            }
            isLBMode = false;
        } else {
            throw new BuildException("Only 'lb' and 'worker' supported as workerType attribute");
        }
    }
}