/*
 * 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 org.apache.cassandra.config;

import java.util.concurrent.TimeUnit;
import java.util.function.Function;

import static org.apache.cassandra.config.DataRateSpec.DataRateUnit.MEBIBYTES_PER_SECOND;

/**
 * Converters for backward compatibility with the old cassandra.yaml where duration, data rate and
 * data storage configuration parameters were provided only by value and the expected unit was part of the configuration
 * parameter name(suffix). (CASSANDRA-15234)
 * It is important to be noted that this converter is not intended to be used when we don't change name of a configuration
 * parameter but we want to add unit. This would always default to the old value provided without a unit at the moment.
 * In case this functionality is needed at some point, please, raise a Jira ticket. There is only one exception handling
 * three parameters (key_cache_save_period, row_cache_save_period, counter_cache_save_period) - the SECONDS_CUSTOM_DURATION
 * converter.
 */
public enum Converters
{
    /**
     * This converter is used when we change the name of a cassandra.yaml configuration parameter but we want to be
     * able to still use the old name too. No units involved.
     */
    IDENTITY(null, null, o -> o, o -> o),
    MILLIS_DURATION_LONG(Long.class, DurationSpec.LongMillisecondsBound.class,
                         DurationSpec.LongMillisecondsBound::new,
                         o -> o == null ? null : o.toMilliseconds()),
    MILLIS_DURATION_INT(Integer.class, DurationSpec.IntMillisecondsBound.class,
                        DurationSpec.IntMillisecondsBound::new,
                        o -> o == null ? null : o.toMilliseconds()),
    MILLIS_DURATION_DOUBLE(Double.class, DurationSpec.IntMillisecondsBound.class,
                           o -> Double.isNaN(o) ? new DurationSpec.IntMillisecondsBound(0) :
                                new DurationSpec.IntMillisecondsBound(o, TimeUnit.MILLISECONDS),
                           o -> (double) o.toMilliseconds()),
    /**
     * This converter is used to support backward compatibility for parameters where in the past -1 was used as a value
     * Example: credentials_update_interval_in_ms = -1 and credentials_update_interval = null are equal.
     */
    MILLIS_CUSTOM_DURATION(Integer.class, DurationSpec.IntMillisecondsBound.class,
                           o -> o == -1 ? null : new DurationSpec.IntMillisecondsBound(o),
                           o -> o == null ? -1 : o.toMilliseconds()),
    SECONDS_DURATION(Integer.class, DurationSpec.IntSecondsBound.class,
                     DurationSpec.IntSecondsBound::new,
                     o -> o == null ? null : o.toSeconds()),
    NEGATIVE_SECONDS_DURATION(Integer.class, DurationSpec.IntSecondsBound.class,
                              o -> o < 0 ? new DurationSpec.IntSecondsBound(0) : new DurationSpec.IntSecondsBound(o),
                              o -> o == null ? null : o.toSeconds()),
    /**
     * This converter is used to support backward compatibility for Duration parameters where we added the opportunity
     * for the users to add a unit in the parameters' values but we didn't change the names. (key_cache_save_period,
     * row_cache_save_period, counter_cache_save_period)
     * Example: row_cache_save_period = 0 and row_cache_save_period = 0s (quantity of 0s) are equal.
     */
    SECONDS_CUSTOM_DURATION(String.class, DurationSpec.IntSecondsBound.class,
                            DurationSpec.IntSecondsBound::inSecondsString,
                            o -> o == null ? null : Long.toString(o.toSeconds())),
    /**
     * This converter is used to support backward compatibility for parameters where in the past -1 was used as a value
     * Example:  index_summary_resize_interval_in_minutes = -1 and  index_summary_resize_interval = null are equal.
     */
    MINUTES_CUSTOM_DURATION(Integer.class, DurationSpec.IntMinutesBound.class,
                            o -> o == -1 ? null : new DurationSpec.IntMinutesBound(o),
                            o -> o == null ? -1 : o.toMinutes()),
    MEBIBYTES_DATA_STORAGE_LONG(Long.class, DataStorageSpec.LongMebibytesBound.class,
                                DataStorageSpec.LongMebibytesBound::new,
                                o -> o == null ? null : o.toMebibytes()),
    MEBIBYTES_DATA_STORAGE_INT(Integer.class, DataStorageSpec.IntMebibytesBound.class,
                               DataStorageSpec.IntMebibytesBound::new,
                               o -> o == null ? null : o.toMebibytes()),
    NEGATIVE_MEBIBYTES_DATA_STORAGE_INT(Integer.class, DataStorageSpec.IntMebibytesBound.class,
                                        o -> o < 0 ? null : new DataStorageSpec.IntMebibytesBound(o),
                                        o -> o == null ? -1 : o.toMebibytes()),
    KIBIBYTES_DATASTORAGE(Integer.class, DataStorageSpec.IntKibibytesBound.class,
                          DataStorageSpec.IntKibibytesBound::new,
                          o -> o == null ? null : o.toKibibytes()),
    BYTES_DATASTORAGE(Integer.class, DataStorageSpec.IntBytesBound.class,
                      DataStorageSpec.IntBytesBound::new,
                      o -> o == null ? null : o.toBytes()),
    /**
     * This converter is used to support backward compatibility for parameters where in the past negative number was used as a value
     * Example: native_transport_max_concurrent_requests_in_bytes_per_ip = -1 and native_transport_max_request_data_in_flight_per_ip = null
     * are equal. All negative numbers are printed as 0 in virtual tables.
     */
    BYTES_CUSTOM_DATASTORAGE(Long.class, DataStorageSpec.LongBytesBound.class,
                             o -> o == -1 ? null : new DataStorageSpec.LongBytesBound(o),
                             o -> o == null ? null : o.toBytes()),
    MEBIBYTES_PER_SECOND_DATA_RATE(Integer.class, DataRateSpec.LongBytesPerSecondBound.class,
                                   i -> new DataRateSpec.LongBytesPerSecondBound(i, MEBIBYTES_PER_SECOND),
                                   o -> o == null ? null : o.toMebibytesPerSecondAsInt()),
    /**
     * This converter is a custom one to support backward compatibility for stream_throughput_outbound and
     * inter_dc_stream_throughput_outbound which were provided in megabits per second prior CASSANDRA-15234.
     */
    MEGABITS_TO_BYTES_PER_SECOND_DATA_RATE(Integer.class, DataRateSpec.LongBytesPerSecondBound.class,
                                           i -> DataRateSpec.LongBytesPerSecondBound.megabitsPerSecondInBytesPerSecond(i),
                                           o -> o == null ? null : o.toMegabitsPerSecondAsInt());
    private final Class<?> oldType;
    private final Class<?> newType;
    private final Function<Object, Object> convert;
    private final Function<Object, Object> reverseConvert;

    <Old, New> Converters(Class<Old> oldType, Class<New> newType, Function<Old, New> convert, Function<New, Old> reverseConvert)
    {
        this.oldType = oldType;
        this.newType = newType;
        this.convert = (Function<Object, Object>) convert;
        this.reverseConvert = (Function<Object, Object>) reverseConvert;
    }

    /**
     * A method to identify what type is needed to be returned by the converter used for a configuration parameter
     * in {@link Replaces} annotation in {@link Config}
     *
     * @return class type
     */
    public Class<?> getOldType()
    {
        return oldType;
    }

    /**
     * Expected return type from {@link #convert(Object)}, and input type to {@link #unconvert(Object)}
     *
     * @return type that {@link #convert(Object)} is expected to return
     */
    public Class<?> getNewType()
    {
        return newType;
    }

    /**
     * Apply the converter specified as part of the {@link Replaces} annotation in {@link Config}
     *
     * @param value we will use from cassandra.yaml to create a new {@link Config} parameter of type {@link DurationSpec},
     *              {@link DataRateSpec} or {@link DataStorageSpec}
     * @return new object of type {@link DurationSpec}, {@link DataRateSpec} or {@link DataStorageSpec}
     */
    public Object convert(Object value)
    {
        if (value == null) return null;
        return convert.apply(value);
    }

    /**
     * Apply the converter specified as part of the {@link Replaces} annotation in {@link Config} to get config parameters'
     * values in the old format pre-CASSANDRA-15234 and in the right units, used in the Virtual Tables to ensure backward
     * compatibility
     *
     * @param value we will use to calculate the output value
     * @return the numeric value
     */
    public Object unconvert(Object value)
    {
        return reverseConvert.apply(value);
    }
}
