<?php

/**
 * Color.php
 *
 * Misc color generation
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program 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 General Public License
 * along with this program.  If not, see <https://www.gnu.org/licenses/>.
 *
 * @link       https://www.librenms.org
 *
 * @copyright  2018 Tony Murray
 * @author     Tony Murray <murraytony@gmail.com>
 */

namespace LibreNMS\Util;

use App\Models\BgpPeer;
use App\Models\Device;
use App\Models\Port;
use LibreNMS\Enum\IfOperStatus;

class Color
{
    /**
     * Get colors for a percentage bar based on current percentage
     *
     * @param  int|float  $percentage
     * @param  int|float  $component_perc_warn
     * @return string[]
     */
    public static function percentage(int|float $percentage, int|float|null $component_perc_warn = null, string $prefix = ''): array
    {
        $perc_warn = 75;

        if (isset($component_perc_warn)) {
            $perc_warn = round($component_perc_warn, 0);
        }

        if ($percentage > $perc_warn) {
            return [
                'left' => $prefix . 'c4323f',
                'right' => $prefix . 'c96a73',
                'middle' => $prefix . 'c75862',
            ];
        }

        if ($percentage > 75) {
            return [
                'left' => $prefix . 'bf5d5b',
                'right' => $prefix . 'eaeaea',
                'middle' => $prefix . 'c97e7d',
            ];
        }

        if ($percentage > 50) {
            return [
                'left' => $prefix . 'bf875b',
                'right' => $prefix . 'eaeaea',
                'middle' => $prefix . 'cca07e',
            ];
        }

        if ($percentage > 25) {
            return [
                'left' => $prefix . '5b93bf',
                'right' => $prefix . 'eaeaea',
                'middle' => $prefix . '7da8c9',
            ];
        }

        return [
            'left' => $prefix . '9abf5b',
            'right' => $prefix . 'eaeaea',
            'middle' => $prefix . 'afcc7c',
        ];
    }

    public static function percent(int|float|null $numerator = null, int|float|null $denominator = null, int|float|null $percent = null): string
    {
        $percent = $percent ? round($percent) : Number::calculatePercent($numerator, $denominator, 0);
        $r = max(0, min(255, 5 * ($percent - 25)));
        $b = max(0, 255 - (5 * ($percent + 25)));

        return sprintf('#%02x%02x%02x', $r, $b, $b);
    }

    /**
     * Get highlight color based on device status
     */
    public static function forDeviceStatus(Device $device): string
    {
        if ($device->disabled) {
            return '#808080';
        }

        if ($device->ignore) {
            return '#000000';
        }

        return $device->status ? '#008000' : '#ff0000';
    }

    /**
     * Get highlight color based on Port status
     */
    public static function forPortStatus(Port $port): string
    {
        // Ignored ports
        if ($port->ignore) {
            return '#000000';
        }

        // Shutdown ports
        if ($port->ifAdminStatus == IfOperStatus::Down) {
            return '#808080';
        }

        // Down Ports
        if ($port->ifOperStatus != IfOperStatus::Up) {
            return '#ff0000';
        }

        // Errored ports
        if ($port->ifInErrors_delta > 0 || $port->ifOutErrors_delta > 0) {
            return '#ffa500';
        }

        // Up ports
        return '#008000';
    }

    /**
     * Get highlight color based on BgpPeer status
     */
    public static function forBgpPeerStatus(BgpPeer $peer): string
    {
        // Session inactive
        if ($peer->bgpPeerAdminStatus !== 'start') {
            return '#000000';
        }

        // Session active but errored
        if ($peer->bgpPeerState !== 'established') {
            return '#ffa500';
        }

        // Session Up
        return '#008000';
    }
}
