<commit_before>/*
 * Copyright 2017 <NAME>
 *
 * Licensed 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 com.axway.ats.action.filesystem;

import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;

import com.axway.ats.action.ActionLibraryConfigurator;
import com.axway.ats.agent.components.system.operations.clients.InternalFileSystemOperations;
import com.axway.ats.common.filesystem.EndOfLineStyle;
import com.axway.ats.common.filesystem.FileMatchInfo;
import com.axway.ats.common.filesystem.FileSystemOperationException;
import com.axway.ats.common.filesystem.FileTailInfo;
import com.axway.ats.common.filesystem.Md5SumMode;
import com.axway.ats.core.filesystem.LocalFileSystemOperations;
import com.axway.ats.core.filesystem.model.IFileSystemOperations;
import com.axway.ats.core.utils.HostUtils;
import com.axway.ats.core.utils.StringUtils;

/**
 * The {@link RemoteFileSystemOperations} class is able to execute file system operations on a remote host
 */
public class RemoteFileSystemOperations implements IFileSystemOperations {

    private String                       atsAgent = null;

    private InternalFileSystemOperations remoteFileSystemOperations;
    private LocalFileSystemOperations    localFileSystemOperations;

    /**
     * Constructor
     *
     * @param atsAgent
     */
    public RemoteFileSystemOperations( String atsAgent ) {

        this.atsAgent = atsAgent;
        this.remoteFileSystemOperations = new InternalFileSystemOperations( atsAgent );
        this.localFileSystemOperations = new LocalFileSystemOperations();
    }

    @Override
    public void createBinaryFile( String fileName, long size, boolean isRandomContent ) {

        createBinaryFile( fileName, size, Integer.MIN_VALUE, Integer.MIN_VALUE, isRandomContent );
    }

    @Override
    public void createBinaryFile( String fileName, long size, long userId, long groupId,
                                  boolean isRandomContent ) {

        try {
            remoteFileSystemOperations.createFile( fileName, null, size, userId, groupId, null,
                                                   isRandomContent, true );
        } catch( Exception e ) {
            throw new FileSystemOperationException( "Unable to create binary file by the name of " + fileName
                                                    + " on " + this.atsAgent, e );
        }

    }

    @Override
    public void createFile( String fileName, String fileContent ) {

        createFile( fileName, fileContent, -1, Integer.MIN_VALUE, Integer.MIN_VALUE, false, null );
    }

    @Override
    public void createFile( String fileName, long size, boolean isRandomContent, EndOfLineStyle eol ) {

        createFile( fileName, size, Integer.MIN_VALUE, Integer.MIN_VALUE, isRandomContent, eol );
    }

    @Override
    public void createFile( String fileName, long size, boolean isRandomContent ) {

        createFile( fileName, size, Integer.MIN_VALUE, Integer.MIN_VALUE, isRandomContent, null );
    }

    @Override
    public void createFile( String filename, String fileContent, long userId, long groupId ) {

        createFile( filename, fileContent, -1, userId, groupId, false, null );
    }

    @Override
    public void createFile( String filename, long size, long userId, long groupId, boolean isRandomContent ) {

        createFile( filename, size, userId, groupId, isRandomContent, null );
    }

    @Override
    public void createFile( String fileName, long size, long userId, long groupId, boolean isRandomContent,
                            EndOfLineStyle eol ) {

        createFile( fileName, null, size, userId, groupId, isRandomContent, eol );
    }

    private void createFile( String fileName, String fileContent, long size, long userId, long groupId,
                             boolean isRandomContent, EndOfLineStyle eol ) {

        try {
            remoteFileSystemOperations.createFile( fileName, fileContent, size, userId, groupId, eol == null
                                                                                                             ? null
                                                                                                             : eol.name(),
                                                   isRandomContent, false );
        } catch( Exception e ) {
            throw new FileSystemOperationException( "Unable to create file by the name of " + fileName
                                                    + " on " + this.atsAgent, e );
        }
    }

    @Override
    public void appendToFile( String fileName, String contentToAdd ) {

        try {
            remoteFileSystemOperations.appendToFile( fileName, contentToAdd );
        } catch( Exception e ) {
            throw new FileSystemOperationException( "Unable to append content to file " + fileName + " on "
                                                    + this.atsAgent, e );
        }
    }

    @Override
    public void copyFile( String fromFile, String toFile, boolean failOnError ) {

        try {
            Integer copyFileStartPort = getCopyFilePortProperty( ActionLibraryConfigurator.getInstance()
                                                                                          .getCopyFileStartPort() );
            Integer copyFileEndPort = getCopyFilePortProperty( ActionLibraryConfigurator.getInstance()
                                                                                        .getCopyFileEndPort() );
            if( copyFileStartPort != null && copyFileStartPort > 0 && copyFileEndPort != null
                && copyFileEndPort > 0 ) {
                remoteFileSystemOperations.setCopyFilePortRange( copyFileStartPort, copyFileEndPort );
            }
            int port = remoteFileSystemOperations.openFileTransferSocket();
            localFileSystemOperations.sendFileTo( fromFile, toFile,
                                                  HostUtils.splitAddressHostAndPort( atsAgent )[0], port,
                                                  failOnError );
            remoteFileSystemOperations.waitForFileTransferCompletion( port );

        } catch( Exception e ) {
            String message = new StringBuilder().append( "Unable to copy file " )
                                                .append( fromFile )
                                                .append( " to " )
                                                .append( toFile )
                                                .append( " on host " )
                                                .append( this.atsAgent )
                                                .toString();
            throw new FileSystemOperationException( message, e );
        }
    }

    public void copyFileTo( String fromFile, String toMachine, String toFile, boolean failOnError ) {

        try {
            Integer copyFileStartPort = getCopyFilePortProperty( ActionLibraryConfigurator.getInstance()
                                                                                          .getCopyFileStartPort() );
            Integer copyFileEndPort = getCopyFilePortProperty( ActionLibraryConfigurator.getInstance()
                                                                                        .getCopyFileEndPort() );
            InternalFileSystemOperations toRemoteFSOperations = new InternalFileSystemOperations( toMachine );

            if( copyFileStartPort != null && copyFileStartPort > 0 && copyFileEndPort != null
                && copyFileEndPort > 0 ) {
                toRemoteFSOperations.setCopyFilePortRange( copyFileStartPort, copyFileEndPort );
            }
            int port = toRemoteFSOperations.openFileTransferSocket();
            this.remoteFileSystemOperations.sendFileTo( fromFile, toFile,
                                                        HostUtils.splitAddressHostAndPort( HostUtils.getAtsAgentIpAndPort( toMachine ) /* append port */ )[0],
                                                        port, failOnError );
            toRemoteFSOperations.waitForFileTransferCompletion( port );

        } catch( Exception e ) {
            String message = new StringBuilder().append( "Unable to copy file " )
                                                .append( fromFile )
                                                .append( " from " )
                                                .append( this.atsAgent )
                                                .append( " to file " )
                                                .append( toFile )<commit_msg>[Action] Check if destination file exists, before executing RemoteSystemOperations.copyFileTo()<commit_after>/*
 * Copyright 2017 <NAME>
 *
 * Licensed 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 com.axway.ats.action.filesystem;

import java.io.FileNotFoundException;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;

import com.axway.ats.action.ActionLibraryConfigurator;
import com.axway.ats.agent.components.system.operations.clients.InternalFileSystemOperations;
import com.axway.ats.common.filesystem.EndOfLineStyle;
import com.axway.ats.common.filesystem.FileMatchInfo;
import com.axway.ats.common.filesystem.FileSystemOperationException;
import com.axway.ats.common.filesystem.FileTailInfo;
import com.axway.ats.common.filesystem.Md5SumMode;
import com.axway.ats.core.filesystem.LocalFileSystemOperations;
import com.axway.ats.core.filesystem.model.IFileSystemOperations;
import com.axway.ats.core.utils.HostUtils;
import com.axway.ats.core.utils.StringUtils;

/**
 * The {@link RemoteFileSystemOperations} class is able to execute file system operations on a remote host
 */
public class RemoteFileSystemOperations implements IFileSystemOperations {

    private String                       atsAgent = null;

    private InternalFileSystemOperations remoteFileSystemOperations;
    private LocalFileSystemOperations    localFileSystemOperations;

    /**
     * Constructor
     *
     * @param atsAgent
     */
    public RemoteFileSystemOperations( String atsAgent ) {

        this.atsAgent = atsAgent;
        this.remoteFileSystemOperations = new InternalFileSystemOperations( atsAgent );
        this.localFileSystemOperations = new LocalFileSystemOperations();
    }

    @Override
    public void createBinaryFile( String fileName, long size, boolean isRandomContent ) {

        createBinaryFile( fileName, size, Integer.MIN_VALUE, Integer.MIN_VALUE, isRandomContent );
    }

    @Override
    public void createBinaryFile( String fileName, long size, long userId, long groupId,
                                  boolean isRandomContent ) {

        try {
            remoteFileSystemOperations.createFile( fileName, null, size, userId, groupId, null,
                                                   isRandomContent, true );
        } catch( Exception e ) {
            throw new FileSystemOperationException( "Unable to create binary file by the name of " + fileName
                                                    + " on " + this.atsAgent, e );
        }

    }

    @Override
    public void createFile( String fileName, String fileContent ) {

        createFile( fileName, fileContent, -1, Integer.MIN_VALUE, Integer.MIN_VALUE, false, null );
    }

    @Override
    public void createFile( String fileName, long size, boolean isRandomContent, EndOfLineStyle eol ) {

        createFile( fileName, size, Integer.MIN_VALUE, Integer.MIN_VALUE, isRandomContent, eol );
    }

    @Override
    public void createFile( String fileName, long size, boolean isRandomContent ) {

        createFile( fileName, size, Integer.MIN_VALUE, Integer.MIN_VALUE, isRandomContent, null );
    }

    @Override
    public void createFile( String filename, String fileContent, long userId, long groupId ) {

        createFile( filename, fileContent, -1, userId, groupId, false, null );
    }

    @Override
    public void createFile( String filename, long size, long userId, long groupId, boolean isRandomContent ) {

        createFile( filename, size, userId, groupId, isRandomContent, null );
    }

    @Override
    public void createFile( String fileName, long size, long userId, long groupId, boolean isRandomContent,
                            EndOfLineStyle eol ) {

        createFile( fileName, null, size, userId, groupId, isRandomContent, eol );
    }

    private void createFile( String fileName, String fileContent, long size, long userId, long groupId,
                             boolean isRandomContent, EndOfLineStyle eol ) {

        try {
            remoteFileSystemOperations.createFile( fileName, fileContent, size, userId, groupId, eol == null
                                                                                                             ? null
                                                                                                             : eol.name(),
                                                   isRandomContent, false );
        } catch( Exception e ) {
            throw new FileSystemOperationException( "Unable to create file by the name of " + fileName
                                                    + " on " + this.atsAgent, e );
        }
    }

    @Override
    public void appendToFile( String fileName, String contentToAdd ) {

        try {
            remoteFileSystemOperations.appendToFile( fileName, contentToAdd );
        } catch( Exception e ) {
            throw new FileSystemOperationException( "Unable to append content to file " + fileName + " on "
                                                    + this.atsAgent, e );
        }
    }

    @Override
    public void copyFile( String fromFile, String toFile, boolean failOnError ) {

        try {
            Integer copyFileStartPort = getCopyFilePortProperty( ActionLibraryConfigurator.getInstance()
                                                                                          .getCopyFileStartPort() );
            Integer copyFileEndPort = getCopyFilePortProperty( ActionLibraryConfigurator.getInstance()
                                                                                        .getCopyFileEndPort() );
            if( copyFileStartPort != null && copyFileStartPort > 0 && copyFileEndPort != null
                && copyFileEndPort > 0 ) {
                remoteFileSystemOperations.setCopyFilePortRange( copyFileStartPort, copyFileEndPort );
            }
            int port = remoteFileSystemOperations.openFileTransferSocket();
            localFileSystemOperations.sendFileTo( fromFile, toFile,
                                                  HostUtils.splitAddressHostAndPort( atsAgent )[0], port,
                                                  failOnError );
            remoteFileSystemOperations.waitForFileTransferCompletion( port );

        } catch( Exception e ) {
            String message = new StringBuilder().append( "Unable to copy file " )
                                                .append( fromFile )
                                                .append( " to " )
                                                .append( toFile )
                                                .append( " on host " )
                                                .append( this.atsAgent )
                                                .toString();
            throw new FileSystemOperationException( message, e );
        }
    }

    public void copyFileTo( String fromFile, String toMachine, String toFile, boolean failOnError ) {

        try {
            
            // check if toFile exists
            if( !remoteFileSystemOperations.doesFileExist( toFile ) ) {
                throw new FileNotFoundException( "File '" + toFile + "' at '" + this.atsAgent
                                                 + "' is missing. You have to create it first by calling FileSystemOperations.createFile() or via some other way." );
            }

            Integer copyFileStartPort = getCopyFilePortProperty( ActionLibraryConfigurator.getInstance()
                                                                                          .getCopyFileStartPort() );
            Integer copyFileEndPort = getCopyFilePortProperty( ActionLibraryConfigurator.getInstance()
                                                                                        .getCopyFileEndPort() );
            InternalFileSystemOperations toRemoteFSOperations = new InternalFileSystemOperations( toMachine );

            if( copyFileStartPort != null && copyFileStartPort > 0 && copyFileEndPort != null
                && copyFileEndPort > 0 ) {
                toRemoteFSOperations.setCopyFilePortRange( copyFileStartPort, copyFileEndPort );
            }
            int port = toRemoteFSOperations.openFileTransferSocket();
            this.remoteFileSystemOperations.sendFileTo( fromFile, toFile,
                                                        HostUtils.splitAddressHostAndPort( HostUtils.getAtsAgentIpAndPort( toMachine ) /* append port */ )[0],
                                                        port, failOnError );
            toRemoteFSOperations.waitForFileTransferCompletion( port );

        } catch( Exception e ) {
            String message = new StringBuilder().append( "Unable to copy file " )
                                                .append( fromFile )
                                                .append( " from " )
                                                .append( this.atsAgent )
                                                .append( " to file " )
                                                .append( toFile )
{'fraction_non_alphanumeric': 0.06963311584126644, 'fraction_numerical': 0.001818376296930153, 'mean_word_length': 1.7178779069767443, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 13, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 136, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2148739', 'n_tokens_mistral': 4066, 'n_tokens_neox': 4080, 'n_words': 1158}