/*
 *  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 java.lang;

import java.io.Serializable;

/**
 * The wrapper for the primitive type {@code boolean}.
 *
 * @since 1.0
 */
public final class Boolean implements Serializable, Comparable<Boolean> {

    private static final long serialVersionUID = -3665804199014368530L;

    /**
     * The boolean value of the receiver.
     */
    private final boolean value;

    /**
     * The {@link Class} object that represents the primitive type {@code
     * boolean}.
     */
    @SuppressWarnings("unchecked")
    public static final Class<Boolean> TYPE = (Class<Boolean>) new boolean[0]
            .getClass().getComponentType();

    // Note: This can't be set to "boolean.class", since *that* is
    // defined to be "java.lang.Boolean.TYPE";

    /**
     * The {@code Boolean} object that represents the primitive value
     * {@code true}.
     */
    public static final Boolean TRUE = new Boolean(true);

    /**
     * The {@code Boolean} object that represents the primitive value
     * {@code false}.
     */
    public static final Boolean FALSE = new Boolean(false);

    /**
     * Constructs a new {@code Boolean} with its boolean value specified by
     * {@code string}. If {@code string} is not {@code null} and is equal to
     * "true" using a non-case sensitive comparison, the result will be a
     * Boolean representing the primitive value {@code true}, otherwise it will
     * be a Boolean representing the primitive value {@code false}.
     *
     * @param string
     *            the string representing a boolean value.
     */
    public Boolean(String string) {
        this(parseBoolean(string));
    }

    /**
     * Constructs a new {@code Boolean} with the specified primitive boolean
     * value.
     *
     * @param value
     *            the primitive boolean value, {@code true} or {@code false}.
     */
    public Boolean(boolean value) {
        this.value = value;
    }

    /**
     * Gets the primitive value of this boolean, either {@code true} or
     * {@code false}.
     *
     * @return this object's primitive value, {@code true} or {@code false}.
     */
    public boolean booleanValue() {
        return value;
    }

    /**
     * Compares this instance with the specified object and indicates if they
     * are equal. In order to be equal, {@code o} must be an instance of
     * {@code Boolean} and have the same boolean value as this object.
     *
     * @param o
     *            the object to compare this boolean with.
     * @return {@code true} if the specified object is equal to this
     *         {@code Boolean}; {@code false} otherwise.
     */
    @Override
    public boolean equals(Object o) {
        return (o == this)
                || ((o instanceof Boolean) && (value == ((Boolean) o).value));
    }

    /**
     * Compares this object to the specified boolean object to determine their
     * relative order.
     *
     * @param that
     *            the boolean object to compare this object to.
     * @return 0 if the value of this boolean and the value of {@code that} are
     *         equal; a positive value if the value of this boolean is
     *         {@code true} and the value of {@code that} is {@code false}; a
     *         negative value if the value if this boolean is {@code false} and
     *         the value of {@code that} is {@code true}.
     * @see java.lang.Comparable
     * @since 1.5
     */
    public int compareTo(Boolean that) {
        if (that == null) {
            throw new NullPointerException();
        }

        if (this.value == that.value) {
            return 0;
        }

        return this.value ? 1 : -1;
    }

    /**
     * Returns an integer hash code for this boolean.
     *
     * @return this boolean's hash code, which is {@code 1231} for {@code true}
     *         values and {@code 1237} for {@code false} values.
     */
    @Override
    public int hashCode() {
        return value ? 1231 : 1237;
    }

    /**
     * Returns a string containing a concise, human-readable description of this
     * boolean.
     *
     * @return "true" if the value of this boolean is {@code true}, "false"
     *         otherwise.
     */
    @Override
    public String toString() {
        return String.valueOf(value);
    }

    /**
     * Returns the {@code boolean} value of the system property identified by
     * {@code string}.
     *
     * @param string
     *            the name of the requested system property.
     * @return {@code true} if the system property named by {@code string}
     *         exists and it is equal to "true" using case insensitive
     *         comparison, {@code false} otherwise.
     * @see System#getProperty(String)
     */
    public static boolean getBoolean(String string) {
        if (string == null || string.length() == 0) {
            return false;
        }
        return (parseBoolean(System.getProperty(string)));
    }

    /**
     * Parses the specified string as a {@code boolean}.
     *
     * @param s
     *            the string representation of a boolean value.
     * @return {@code true} if {@code s} is not {@code null} and is equal to
     *         {@code "true"} using case insensitive comparison, {@code false}
     *         otherwise.
     * @since 1.5
     */
    public static boolean parseBoolean(String s) {
        return "true".equalsIgnoreCase(s); //$NON-NLS-1$
    }

    /**
     * Converts the specified boolean to its string representation.
     *
     * @param value
     *            the boolean to convert.
     * @return "true" if {@code value} is {@code true}, "false" otherwise.
     */
    public static String toString(boolean value) {
        return String.valueOf(value);
    }

    /**
     * Parses the specified string as a boolean value.
     *
     * @param string
     *            the string representation of a boolean value.
     * @return {@code Boolean.TRUE} if {@code string} is equal to "true" using
     *         case insensitive comparison, {@code Boolean.FALSE} otherwise.
     * @see #parseBoolean(String)
     */
    public static Boolean valueOf(String string) {
        return parseBoolean(string) ? Boolean.TRUE : Boolean.FALSE;
    }

    /**
     * Returns a {@code Boolean} instance for the specified boolean value.
     * <p>
     * If it is not necessary to get a new {@code Boolean} instance, it is
     * recommended to use this method instead of the constructor, since it
     * returns its static instances, which results in better performance.
     *
     * @param b
     *            the boolean to convert to a {@code Boolean}.
     * @return {@code Boolean.TRUE} if {@code b} is equal to {@code true},
     *         {@code Boolean.FALSE} otherwise.
     */
    public static Boolean valueOf(boolean b) {
        return b ? Boolean.TRUE : Boolean.FALSE;
    }
}
