/**
 * CreditCardFraudDetection.java
 *
 * Copyright (C) 2005 MaxMind LLC.  All Rights Reserved.
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */

package com.maxmind.ws;

import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.HashMap;

public class CreditCardFraudDetection extends HTTPBase {
    static String[] allowedfields = { "i", "domain", "city", "region",
            "postal", "country", "bin", "binName", "binPhone", "custPhone",
            "license_key", "requested_type", "forwardedIP", "emailMD5",
            "shipAddr", "shipCity", "shipRegion", "shipPostal", "shipCountry",
            "txnID", "sessionID", "usernameMD5", "passwordMD5", "user_agent",
            "accept_language", "avs_result", "cvv_result", "order_amount",
            "order_currency", "shopID", "txn_type" };
    char[] hexchar = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a',
            'b', 'c', 'd', 'e', 'f' };

    public CreditCardFraudDetection() {
        initFields();
        setIsSecure(true);
    }

    private void initFields() {
        url = "app/ccv2r";
        check_field = "countryMatch";
        allowed_fields = new HashMap<String, Integer>();
        for (final String allowedfield : allowedfields) {
            allowed_fields.put(allowedfield, new Integer(1));
        }
    }

    public CreditCardFraudDetection(boolean s) {
        initFields();
        setIsSecure(s);
    }

    private CreditCardFraudDetection(Builder builder) {
        initFields();
        setIsSecure(builder.isSecure);
        this.proxyHost = builder.proxyHost;
        this.proxyPort = builder.proxyPort;
        this.useSystemProxies = builder.systemProxies;
    }

    @Override
    protected String filter_field(String key, String value) {
        if (("emailMD5".equals(key) && value.indexOf('@') != -1)
                || (("usernameMD5".equals(key) || "passwordMD5".equals(key)) && value
                        .length() != 32)) {
            try {
                final MessageDigest md = MessageDigest.getInstance("MD5");
                md.update(value.toLowerCase().getBytes());
                final byte[] b = md.digest();
                final StringBuffer md5str = new StringBuffer();
                for (final byte element : b) {
                    md5str.append(hexchar[(element & 0xff) >> 4]);
                    md5str.append(hexchar[element & 15]);
                }
                return md5str.toString();
            } catch (final NoSuchAlgorithmException e) {
                System.out.println("algorithm not support\n");
            }
        }
        return value;
    }

    public static class Builder {
        private boolean systemProxies = false;
        private String proxyHost = null;
        private int proxyPort = -1;
        private boolean isSecure = true;

        public Builder() { }

        public Builder useSystemProxies() {
            systemProxies = true;
            return this;
        }
        public Builder useProxy(String proxyHost, int proxyPort) {
            this.proxyHost = proxyHost;
            this.proxyPort = proxyPort;
            return this;
        }
        public CreditCardFraudDetection build() {
            return new CreditCardFraudDetection(this);
        }

        public CreditCardFraudDetection buildUnsecure() {
            this.isSecure = false;
            return new CreditCardFraudDetection(this);
        }
    }
}

@@ -3704,12 +3704,9 @@
 der 
-useP
+p
 roxy
@@ -3848,32 +3848,33 @@
 this;%0A        %7D%0A
+%0A
         public C
@@ -3876,96 +3876,94 @@
 lic 
-CreditCardFraudDetection build() %7B%0A            return new CreditCardFraudDetection(
+Builder withoutSecurity() %7B%0A            this.isSecure = false;%0A            return 
 this
-)
 ;%0A  
@@ -3962,33 +3962,32 @@
 this;%0A        %7D%0A
-%0A
         public C
@@ -4019,55 +4019,12 @@
 uild
-Unsecure() %7B%0A            this.isSecure = false;
+() %7B
 %0A   
@@ -4081,20 +4081,21 @@
 ;%0A        %7D%0A
+%0A
     %7D%0A%7D%0A

update according to pull request comments