/*
 * 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.sshd.client.subsystem.sftp;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.Random;

import org.apache.sshd.server.subsystem.sftp.SftpSubsystem;
import org.apache.sshd.util.test.BaseTestSupport;
import org.junit.FixMethodOrder;
import org.junit.Test;
import org.junit.runners.MethodSorters;

/**
 * @author <a href="mailto:dev@mina.apache.org">Apache MINA SSHD Project</a>
 */
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
public class SftpVersionSelectorTest extends BaseTestSupport {
    public SftpVersionSelectorTest() {
        super();
    }

    @Test
    public void testCurrentVersionSelector() {
        List<Integer> available = new ArrayList<>();
        Random rnd = new Random(System.nanoTime());
        for (int expected = SftpSubsystem.LOWER_SFTP_IMPL; expected <= SftpSubsystem.HIGHER_SFTP_IMPL; expected++) {
            assertEquals("Mismatched directly selected for available=" + available, expected, SftpVersionSelector.CURRENT.selectVersion(expected, available));
            available.add(Integer.valueOf(expected));
        }

        for (int expected = SftpSubsystem.LOWER_SFTP_IMPL; expected <= SftpSubsystem.HIGHER_SFTP_IMPL; expected++) {
            for (int index = 0; index < available.size(); index++) {
                Collections.shuffle(available, rnd);
                assertEquals("Mismatched suffling selected for current=" + expected + ", available=" + available,
                        expected, SftpVersionSelector.CURRENT.selectVersion(expected, available));
            }
        }
    }

    @Test
    public void testFixedVersionSelector() {
        final int fixedValue = 7365;
        testVersionSelector(SftpVersionSelector.Utils.fixedVersionSelector(fixedValue), fixedValue);
    }

    @Test
    public void testPreferredVersionSelector() {
        List<Integer> available = new ArrayList<>();
        for (int version = SftpSubsystem.LOWER_SFTP_IMPL; version <= SftpSubsystem.HIGHER_SFTP_IMPL; version++) {
            available.add(Integer.valueOf(version));
        }

        List<Integer> preferred = new ArrayList<>(available);
        List<Integer> unavailable = Arrays.asList(7365, 3777347);
        Random rnd = new Random(System.nanoTime());
        for (int index = 0; index < preferred.size(); index++) {
            Collections.shuffle(preferred, rnd);
            SftpVersionSelector selector = SftpVersionSelector.Utils.preferredVersionSelector(preferred);
            int expected = preferred.get(0);

            for (int current = SftpSubsystem.LOWER_SFTP_IMPL; current <= SftpSubsystem.HIGHER_SFTP_IMPL; current++) {
                assertEquals("Mismatched selected for current= " + current + ", available=" + available + ", preferred=" + preferred,
                             expected, selector.selectVersion(current, available));

                try {
                    Collections.shuffle(unavailable, rnd);
                    int version = unavailable.get(0);
                    int actual = selector.selectVersion(version, unavailable);
                    fail("Unexpected selected version (" + actual + ")"
                            + " for current= " + version
                            + ", available=" + unavailable
                            + ", preferred=" + preferred);
                } catch (IllegalStateException e) {
                    // expected
                }
            }
        }
    }

    @Test
    public void testMaximumVersionSelector() {
        testVersionSelector(SftpVersionSelector.MAXIMUM, SftpSubsystem.HIGHER_SFTP_IMPL);
    }

    @Test
    public void testMinimumVersionSelector() {
        testVersionSelector(SftpVersionSelector.MINIMUM, SftpSubsystem.LOWER_SFTP_IMPL);
    }

    private static void testVersionSelector(SftpVersionSelector selector, int expected) {
        List<Integer> available = new ArrayList<>();
        for (int version = SftpSubsystem.LOWER_SFTP_IMPL; version <= SftpSubsystem.HIGHER_SFTP_IMPL; version++) {
            available.add(Integer.valueOf(version));
        }

        Random rnd = new Random(System.nanoTime());
        for (int current = SftpSubsystem.LOWER_SFTP_IMPL; current <= SftpSubsystem.HIGHER_SFTP_IMPL; current++) {
            for (int index = 0; index < available.size(); index++) {
                assertEquals("Mismatched selection for current=" + current + ", availble=" + available, expected, selector.selectVersion(current, available));
                Collections.shuffle(available, rnd);
            }
        }
    }
}
