<?php
/**
* 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.
*/

namespace Apache\Log4php;

use Apache\Log4php\Helpers\OptionConverter;

use Exception;

/**
 * A base class from which all classes which have configurable properties are
 * extended. Provides a generic setter with integrated validation.
 *
 * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License, Version 2.0
 * @link http://logging.apache.org/log4php
 * @since 2.2
 */
abstract class Configurable
{
    /** Setter function for boolean type. */
    protected function setBoolean($property, $value)
    {
        try {
            $this->$property = OptionConverter::toBooleanEx($value);
        } catch (Exception $ex) {
            $value = var_export($value, true);
            $this->warn(
                "Invalid value given for '$property' property: [$value]. " .
                "Expected a boolean value. Property not changed."
            );
        }
    }

    /** Setter function for integer type. */
    protected function setInteger($property, $value)
    {
        try {
            $this->$property = OptionConverter::toIntegerEx($value);
        } catch (Exception $ex) {
            $value = var_export($value, true);
            $this->warn(
                "Invalid value given for '$property' property: [$value]. Expected an integer. " .
                "Property not changed."
            );
        }
    }

    /** Setter function for Level values. */
    protected function setLevel($property, $value)
    {
        try {
            $this->$property = OptionConverter::toLevelEx($value);
        } catch (Exception $ex) {
            $value = var_export($value, true);
            $this->warn(
                "Invalid value given for '$property' property: [$value]. Expected a level value. " .
                "Property not changed."
            );
        }
    }

    /** Setter function for integer type. */
    protected function setPositiveInteger($property, $value)
    {
        try {
            $this->$property = OptionConverter::toPositiveIntegerEx($value);
        } catch (Exception $ex) {
            $value = var_export($value, true);
            $this->warn(
                "Invalid value given for '$property' property: [$value]. Expected a positive integer. " .
                "Property not changed."
            );
        }
    }

    /** Setter for file size. */
    protected function setFileSize($property, $value)
    {
        try {
            $this->$property = OptionConverter::toFileSizeEx($value);
        } catch (Exception $ex) {
            $value = var_export($value, true);
            $this->warn(
                "Invalid value given for '$property' property: [$value]. Expected a file size value.  " .
                "Property not changed."
            );
        }
    }

    /** Setter function for numeric type. */
    protected function setNumeric($property, $value)
    {
        try {
            $this->$property = OptionConverter::toNumericEx($value);
        } catch (Exception $ex) {
            $value = var_export($value, true);
            $this->warn(
                "Invalid value given for '$property' property: [$value]. Expected a number. " .
                "Property not changed."
            );
        }
    }

    /** Setter function for string type. */
    protected function setString($property, $value, $nullable = false)
    {
        if ($value === null) {
            if ($nullable) {
                $this->$property= null;
            } else {
                $this->warn(
                    "Null value given for '$property' property. Expected a string. " .
                    "Property not changed."
                );
            }
        } else {
            try {
                $value = OptionConverter::toStringEx($value);
                $this->$property = OptionConverter::substConstants($value);
            } catch (Exception $ex) {
                $value = var_export($value, true);
                $this->warn(
                    "Invalid value given for '$property' property: [$value]. Expected a string. " .
                    "Property not changed."
                );
            }
        }
    }

    /** Triggers a warning. */
    protected function warn($message)
    {
        $class = get_class($this);
        trigger_error("log4php: $class: $message", E_USER_WARNING);
    }
}
