// 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 com.cloud.network.lb;

import java.util.List;

import com.cloud.network.rules.FirewallRule;
import com.cloud.network.rules.LoadBalancer;
import com.cloud.utils.Pair;

public class LoadBalancingRule implements FirewallRule, LoadBalancer{
    private LoadBalancer lb;
    private List<LbDestination> destinations;
    private List<LbStickinessPolicy> stickinessPolicies;
    
    public LoadBalancingRule(LoadBalancer lb, List<LbDestination> destinations, List<LbStickinessPolicy> stickinessPolicies) { 
        this.lb = lb;
        this.destinations = destinations;
        this.stickinessPolicies = stickinessPolicies;
    }
    
    @Override
    public long getId() {
        return lb.getId();
    }
    
    @Override
    public long getAccountId() {
        return lb.getAccountId();
    }
    
    @Override
    public long getDomainId() {
        return lb.getDomainId();
    }
    
    @Override
    public String getName() {
        return lb.getName();
    }
    
    @Override
    public String getDescription() {
        return lb.getDescription();
    }

    public int getDefaultPortStart() {
        return lb.getDefaultPortStart();
    }
    
    @Override
    public int getDefaultPortEnd() {
        return lb.getDefaultPortEnd();
    }

    @Override
    public String getAlgorithm() {
        return lb.getAlgorithm();
    }
    
    @Override
    public String getXid() {
        return lb.getXid();
    }
    
    @Override
    public Long getSourceIpAddressId() {
        return lb.getSourceIpAddressId();
    }
    
    @Override
    public Integer getSourcePortStart() {
        return lb.getSourcePortStart();
    }
    
    @Override
    public Integer getSourcePortEnd() {
        return lb.getSourcePortEnd();
    }

    @Override
    public String getProtocol() {
        return lb.getProtocol();
    }
    
    @Override
    public Purpose getPurpose() {
        return Purpose.LoadBalancing;
    }
    
    @Override
    public State getState() {
        return lb.getState();
    }
    
    @Override
    public long getNetworkId() {
        return lb.getNetworkId();
    }
    
    public LoadBalancer getLb() {
        return lb;
    }

    public List<LbDestination> getDestinations() {
        return destinations;
    }
    
    public List<LbStickinessPolicy> getStickinessPolicies() {
        return stickinessPolicies;
    }
    
    
    public interface Destination {
        String getIpAddress();
        int getDestinationPortStart();
        int getDestinationPortEnd();
        boolean isRevoked();
    }

    public static class LbStickinessPolicy {
        private String _methodName;
        private List<Pair<String, String>> _params;
        private boolean _revoke;

        public LbStickinessPolicy(String methodName, List<Pair<String, String>> params, boolean revoke) {
            this._methodName = methodName;
            this._params = params;
            this._revoke = revoke;
        }

        public LbStickinessPolicy(String methodName, List<Pair<String, String>> params) {
            this._methodName = methodName;
            this._params = params;
            this._revoke = false;
        }
        
        public String getMethodName() {
            return _methodName;
        }

        public List<Pair<String, String>> getParams() {
            return _params;
        }

        public boolean isRevoked() {
            return _revoke;
        }
    }
    
    public static class LbDestination implements Destination {
        private int portStart;
        private int portEnd;
        private String ip;
        boolean revoked;
        
        public LbDestination(int portStart, int portEnd, String ip, boolean revoked) {
            this.portStart = portStart;
            this.portEnd = portEnd;
            this.ip = ip;
            this.revoked = revoked;
        }
        
        public String getIpAddress() {
            return ip;
        }
        public int getDestinationPortStart() {
            return portStart;
        }
        public int getDestinationPortEnd() {
            return portEnd;
        }
        
        public boolean isRevoked() {
            return revoked;
        }
       
        public void setRevoked(boolean revoked) {
            this.revoked = revoked;
        }
    }
    
    @Override
    public Integer getIcmpCode() {
        return null;
    }
    
    @Override
    public Integer getIcmpType() {
        return null;
    }
    
    @Override
    public List<String> getSourceCidrList() {
        return null;
    }
    
    @Override
    public Long getRelated() {
        return null;
    }

	@Override
	public FirewallRuleType getType() {
		return FirewallRuleType.User;
	}
	
    @Override
    public TrafficType getTrafficType() {
        return null;
    }
}
