/*
 * 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.commons.vfs2.provider.sftp;

import java.net.URI;

import org.apache.commons.vfs2.FileObject;
import org.apache.commons.vfs2.FileSystemManager;
import org.apache.commons.vfs2.FileSystemOptions;
import org.apache.commons.vfs2.PermissionsTests;
import org.apache.commons.vfs2.ProviderReadTests;

import com.jcraft.jsch.TestIdentityRepositoryFactory;

import junit.framework.Test;

public class SftpProviderStreamProxyModeTestCase extends AbstractSftpProviderTestCase {
    @Override
    protected boolean isExecChannelClosed() {
        return false;
    }

    // --- VFS-440: stream proxy test suite
    // We override the addBaseTests method so that only
    // one test is run (we just test that the input/output are correctly forwarded, and
    // hence if the reading test succeeds/fails the other will also succeed/fail)
    public static Test suite() throws Exception {
        final SftpProviderTestSuite suite = new SftpProviderTestSuite(new SftpProviderStreamProxyModeTestCase()) {
            @Override
            protected void addBaseTests() throws Exception {
                // Just tries to read
                addTests(ProviderReadTests.class);
                // VFS-405: set/get permissions
                addTests(PermissionsTests.class);
            }
        };
        return suite;
    }

    @Override
    public FileObject getBaseTestFolder(final FileSystemManager manager) throws Exception {
        String uri = getSystemTestUriOverride();
        if (uri == null) {
            uri = ConnectionUri;
        }

        final FileSystemOptions fileSystemOptions = new FileSystemOptions();
        final SftpFileSystemConfigBuilder builder = SftpFileSystemConfigBuilder.getInstance();
        builder.setStrictHostKeyChecking(fileSystemOptions, "no");
        builder.setUserInfo(fileSystemOptions, new TrustEveryoneUserInfo());
        builder.setIdentityRepositoryFactory(fileSystemOptions, new TestIdentityRepositoryFactory());

        final FileSystemOptions proxyOptions = (FileSystemOptions) fileSystemOptions.clone();

        final URI parsedURI = new URI(uri);
        final String userInfo = parsedURI.getUserInfo();
        final String[] userFields = userInfo == null ? null : userInfo.split(":", 2);

        builder.setProxyType(fileSystemOptions, SftpFileSystemConfigBuilder.PROXY_STREAM);
        if (userFields != null) {
            if (userFields.length > 0) {
                builder.setProxyUser(fileSystemOptions, userFields[0]);
            }
            if (userFields.length > 1) {
                builder.setProxyPassword(fileSystemOptions, userFields[1]);
            }
        }
        builder.setProxyHost(fileSystemOptions, parsedURI.getHost());
        builder.setProxyPort(fileSystemOptions, parsedURI.getPort());
        builder.setProxyCommand(fileSystemOptions, SftpStreamProxy.NETCAT_COMMAND);
        builder.setProxyOptions(fileSystemOptions, proxyOptions);
        builder.setProxyPassword(fileSystemOptions, parsedURI.getAuthority());

        // Set up the new URI
        if (userInfo == null) {
            uri = String.format("sftp://localhost:%d", parsedURI.getPort());
        } else {
            uri = String.format("sftp://%s@localhost:%d", userInfo, parsedURI.getPort());
        }


        final FileObject fileObject = manager.resolveFile(uri, fileSystemOptions);
        this.fileSystem = (SftpFileSystem) fileObject.getFileSystem();
        return fileObject;
    }
}
