/*
 * ARX: Powerful Data Anonymization
 * Copyright 2012 - 2017 Fabian Prasser, Florian Kohlmayer and contributors
 * 
 * Licensed 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.deidentifier.arx;

import java.io.Serializable;

/**
 * Basic configuration of monetary amounts, such as the publisher's benefit
 * per record or the per-record fine fine for a successful re-identification attack.
 * These parameters can be used to perform monetary cost/benefit analyses, e.g. 
 * using a game-theoretic approach.
 * 
 * @author Fabian Prasser
 */
public class ARXCostBenefitConfiguration implements Serializable {
    
    /** SVUID*/
    private static final long serialVersionUID = -560679186676701860L;

    /**
     * Creates a new instance
     * @return
     */
    public static ARXCostBenefitConfiguration create() {
        return new ARXCostBenefitConfiguration();
    }

    /** Basic parameters */
    private double             publisherBenefit  = 1200d;
    /** Basic parameters */
    private double             publisherLoss     = 300d;
    /** Basic parameters */
    private double             adversaryGain     = 300d;
    /** Basic parameters */
    private double             adversaryCost     = 4d;
    
    /**
     * Hide constructor
     */
    protected ARXCostBenefitConfiguration() {
        // Empty by design
    }

    @Override
    public ARXCostBenefitConfiguration clone() {
        ARXCostBenefitConfiguration result = new ARXCostBenefitConfiguration();
        result.publisherBenefit = this.publisherBenefit;
        result.publisherLoss = this.publisherLoss;
        result.adversaryGain = this.adversaryGain;
        result.adversaryCost = this.adversaryCost;
        return result;
    }

    /**
     * Returns the amount of money needed by an attacker for trying to re-identify a single record
     * @return the adversaryCost
     */
    public double getAdversaryCost() {
        return adversaryCost;
    }

    /**
     * Returns the amount of money earned by an attacker for successfully re-identifying a single record
     * @return the adversaryGain
     */
    public double getAdversaryGain() {
        return adversaryGain;
    }
    
    /**
     * Returns the amount of money earned by the data publisher for publishing a single record
     * @return the publisherBenefit
     */
    public double getPublisherBenefit() {
        return publisherBenefit;
    }

    /**
     * Returns the amount of money lost by the data publisher, e.g. due to a fine, if a single record is attacked successfully
     * @return the publisherLoss
     */
    public double getPublisherLoss() {
        return publisherLoss;
    }

    /**
     * Sets the amount of money needed by an attacker for trying to re-identify a single record
     * @param adversaryCost the adversaryCost to set
     */
    public ARXCostBenefitConfiguration setAdversaryCost(double adversaryCost) {
        this.adversaryCost = adversaryCost;
        return this;
    }

    /**
     * Sets the amount of money earned by an attacker for successfully re-identifying a single record
     * @param adversaryGain the adversaryGain to set
     */
    public ARXCostBenefitConfiguration setAdversaryGain(double adversaryGain) {
        this.adversaryGain = adversaryGain;
        return this;
    }

    /**
     * Sets the amount of money earned by the data publisher for publishing a single record
     * @param publisherBenefit the publisherBenefit to set
     */
    public ARXCostBenefitConfiguration setPublisherBenefit(double publisherBenefit) {
        this.publisherBenefit = publisherBenefit;
        return this;
    }
    
    /**
     * Sets the amount of money lost by the data publisher, e.g. due to a fine, if a single record is attacked successfully
     * @param publisherLoss the publisherLoss to set
     */
    public ARXCostBenefitConfiguration setPublisherLoss(double publisherLoss) {
        this.publisherLoss = publisherLoss;
        return this;
    }
    
    @Override
    public String toString() {
        StringBuilder builder = new StringBuilder();   
        builder.append("[benefit=").append(publisherBenefit).append(", loss=");
        builder.append(publisherLoss).append(", gain=").append(adversaryGain).append(", cost=").append(adversaryCost).append("]");
        return builder.toString();
    }
}

@@ -3409,24 +3409,81 @@
 saryCost) %7B%0A
+        checkParameter(%22adversary cost%22, adversaryCost);%0A
         this
@@ -3506,32 +3506,32 @@
  adversaryCost;%0A
-
         return t
@@ -3789,24 +3789,81 @@
 saryGain) %7B%0A
+        checkParameter(%22adversary gain%22, adversaryGain);%0A
         this
@@ -4171,24 +4171,87 @@
 rBenefit) %7B%0A
+        checkParameter(%22publisher benefit%22, publisherBenefit);%0A
         this
@@ -4589,24 +4589,81 @@
 sherLoss) %7B%0A
+        checkParameter(%22publisher loss%22, publisherLoss);%0A
         this
@@ -5034,24 +5034,24 @@
 ppend(%22%5D%22);%0A
-
         retu
@@ -5079,10 +5079,361 @@
 ;%0A    %7D%0A
+    %0A    /**%0A     * Checks a given parameter%0A     * @param parameter%0A     * @param value%0A     */%0A    private void checkParameter(String parameter, double value) %7B%0A        if (value %3C 0d %7C%7C Double.isNaN(value) %7C%7C Double.isInfinite(value)) %7B%0A            throw new IllegalArgumentException(%22Parameter '%22 + parameter + %22' out of range!%22);%0A        %7D%0A    %7D%0A
 %7D%0A

Add some sanity checks