/*
 * 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.sidecar.common;

import java.util.ArrayList;
import java.util.List;
import javax.annotation.concurrent.NotThreadSafe;
import com.google.common.annotations.VisibleForTesting;

/**
 * Manages multiple Cassandra versions
 */
public class CassandraVersionProvider
{
    final ArrayList<ICassandraFactory> versions;

    public CassandraVersionProvider(ArrayList<ICassandraFactory> versions)
    {
        this.versions = versions;
    }

    @VisibleForTesting
    public List<ICassandraFactory> getAllVersions()
    {
        return this.versions;
    }

    /**
     * For the provided CassandraVersion, return a new ICassandraFactory instance
     * that meets the minimum version requirements
     * That factory can be used to create an ICassandraAdapter
     * @param requestedVersion
     * @return
     */
    public ICassandraFactory getCassandra(SimpleCassandraVersion requestedVersion)
    {
        ICassandraFactory result = versions.get(0);

        for (ICassandraFactory f : versions)
        {
            SimpleCassandraVersion currentMinVersion = SimpleCassandraVersion.create(result);
            SimpleCassandraVersion nextVersion = SimpleCassandraVersion.create(f);

            // skip if we can rule this out early
            if (nextVersion.isGreaterThan(requestedVersion)) continue;

            if (requestedVersion.isGreaterThan(currentMinVersion))
            {
                result = f;
            }
        }
        return result;
    }

    /**
     * Convenience method for getCassandra, converts the String version to a typed one
     * @param requestedVersion
     * @return
     */
    ICassandraFactory getCassandra(String requestedVersion)
    {
        SimpleCassandraVersion version = SimpleCassandraVersion.create(requestedVersion);
        return getCassandra(version);
    }

    /**
     * Builder for VersionProvider
     */
    @NotThreadSafe
    public static class Builder
    {
        ArrayList<ICassandraFactory> versions;
        public Builder()
        {
            versions = new ArrayList<>();
        }

        public CassandraVersionProvider build()
        {
            if (versions.isEmpty())
            {
                throw new IllegalStateException("At least one ICassandraFactory is required");
            }
            return new CassandraVersionProvider(versions);
        }
        public Builder add(ICassandraFactory version)
        {
            versions.add(version);
            return this;
        }

    }
}
