/*
 * Copyright 2013-2026, Seqera Labs
 *
 * 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 nextflow.extension

import groovyx.gpars.dataflow.DataflowVariable
import nextflow.Channel
import nextflow.Global
import spock.lang.Specification

import static test.ScriptHelper.runDataflow
/**
 *
 * @author Paolo Di Tommaso <paolo.ditommaso@gmail.com>
 */
class DataflowMergeExtensionTest extends Specification {

    def cleanup() {
        assert !Global.session.dag.isEmpty()
    }

    def 'should merge with open array' () {
        when:
        def result = runDataflow {
            def alpha = Channel.of(1, 3, 5)
            def beta =  Channel.of(2, 4, 6)
            def delta = Channel.of(7, 8, 1)
            alpha.merge( beta, delta )
        }
        then:
        result.val == [1,2,7]
        result.val == [3,4,8]
        result.val == [5,6,1]
        result.val == Channel.STOP
    }

    def 'should merge with with default'() {

        when:
        def result = runDataflow {
            def left =  Channel.of(1, 3, 5)
            def right = Channel.of(2, 4, 6)
            left.merge(right)
        }
        then:
        result.val == [1,2]
        result.val == [3,4]
        result.val == [5,6]
        result.val == Channel.STOP

        when:
        result = runDataflow {
            def left  = Channel.of(1, 2, 3)
            def right = Channel.of(['a','b'], ['p','q'], ['x','z'])
            left.merge(right)
        }
        then:
        result.val == [1, 'a','b']
        result.val == [2, 'p','q']
        result.val == [3, 'x','z']
        result.val == Channel.STOP

        when:
        result = runDataflow {
            def left  = Channel.of('A','B','C')
            def right = Channel.of(['a',[1,2,3]], ['b',[3,4,5]], ['c',[6,7,8]])
            left.merge(right)
        }
        then:
        result.val == ['A', 'a', [1,2,3]]
        result.val == ['B', 'b', [3,4,5]]
        result.val == ['C', 'c', [6,7,8]]
        result.val == Channel.STOP

    }

    def 'should merge with queue'() {

        when:
        def result = runDataflow {
            def alpha = Channel.of(1, 3, 5)
            def beta = Channel.of(2, 4, 6)
            alpha.merge(beta) { a,b -> [a, b+1] }
        }

        then:
        result.val == [1,3]
        result.val == [3,5]
        result.val == [5,7]
        result.val == Channel.STOP
    }

    def 'should merge with variables with custom closure'() {

        when:
        def result = runDataflow {
            def alpha = Channel.value('Hello')
            def beta = Channel.value('World')
            alpha.merge(beta) { a,b -> [b, a] }
        }
        then:
        result instanceof DataflowVariable
        result.val == ['World', 'Hello']
        result.val == ['World', 'Hello']
    }

    def 'should merge variables' () {
        when:
        def result = runDataflow {
            def alpha = Channel.value('Hello')
            def beta = Channel.value('World')
            alpha.merge(beta)
        }
        then:
        result instanceof DataflowVariable
        result.val == ['Hello','World']
        result.val == ['Hello','World']
    }

}
