/*
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.edgent.test.providers.dev;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;

import java.util.Collection;

import org.apache.edgent.execution.Job;
import org.apache.edgent.execution.Submitter;
import org.apache.edgent.graph.Graph;
import org.apache.edgent.graph.Vertex;
import org.apache.edgent.metrics.oplets.CounterOp;
import org.apache.edgent.oplet.Oplet;
import org.apache.edgent.providers.development.DevelopmentProvider;
import org.apache.edgent.streamscope.oplets.StreamScope;
import org.apache.edgent.topology.TopologyAbstractTest;
import org.apache.edgent.topology.TStream;
import org.apache.edgent.topology.Topology;
import org.apache.edgent.topology.tester.Condition;
import org.junit.Test;

public class DevelopmentProviderTest extends TopologyAbstractTest {

    @Override
    public DevelopmentProvider createTopologyProvider() {
        try {
            return new DevelopmentProvider();
        }
        catch (Exception e) {
            throw new RuntimeException(e);
        }
    }
  
    @Override
    public Submitter<Topology, Job> createSubmitter() {
        return (DevelopmentProvider) getTopologyProvider();
    }

    // DevelopmentProvider inserts CounterOp metric oplets into the org.apache.edgent.graph
    @Test
    public void testMetricsEverywhere() throws Exception {

        Topology t = newTopology();
        TStream<String> s = t.strings("a", "b", "c");

        // Condition inserts a sink
        Condition<Long> tc = t.getTester().tupleCount(s, 3);

        Graph g = t.graph();
        Collection<Vertex<? extends Oplet<?, ?>, ?, ?>> vertices = g.getVertices();
        
        // Two vertices before submission
        assertEquals(2, vertices.size());

        complete(t, tc);
  
        // At least three vertices after submission
        // (provide may have added other oplets as well)
        Collection<Vertex<? extends Oplet<?, ?>, ?, ?>> verticesAfterSubmit = g.getVertices();
        assertTrue("size="+verticesAfterSubmit.size(), verticesAfterSubmit.size() >= 3);
        
        // There is exactly one vertex for a metric oplet
        int numOplets = 0;
        for (Vertex<? extends Oplet<?, ?>, ?, ?> v : verticesAfterSubmit) {
            Oplet<?,?> oplet = v.getInstance();
            if (oplet instanceof CounterOp) {
                numOplets++;
            }
        }
        assertEquals(1, numOplets);
    }

    // DevelopmentProvider inserts StreamScope oplets into the org.apache.edgent.graph
    @Test
    public void testStreamScopesEverywhere() throws Exception {

        Topology t = newTopology();
        TStream<String> s = t.strings("a", "b", "c");
        s = s.map(tuple -> tuple)
            .filter(tuple -> true);

        // Condition inserts a sink
        Condition<Long> tc = t.getTester().tupleCount(s, 3);

        Graph g = t.graph();
        Collection<Vertex<? extends Oplet<?, ?>, ?, ?>> vertices = g.getVertices();
        
        // Four vertices before submission
        assertEquals(4, vertices.size());

        complete(t, tc);
  
        // At least 4+3 vertices after submission
        // (provide may have added other oplets as well)
        Collection<Vertex<? extends Oplet<?, ?>, ?, ?>> verticesAfterSubmit = g.getVertices();
        assertTrue("size="+verticesAfterSubmit.size(), verticesAfterSubmit.size() >= 7);
        
        // There are exactly 3 vertex for a StreamScope oplet
        int numOplets = 0;
        for (Vertex<? extends Oplet<?, ?>, ?, ?> v : verticesAfterSubmit) {
            Oplet<?,?> oplet = v.getInstance();
            if (oplet instanceof StreamScope) {
                numOplets++;
            }
        }
        assertEquals(3, numOplets);
    }
}
