/*
 * Copyright © 2015 Cask Data, Inc.
 *
 * 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 co.cask.cdap.internal.app.runtime.flow;

import co.cask.cdap.api.flow.Flow;
import co.cask.cdap.api.flow.FlowConfigurer;
import co.cask.cdap.api.flow.FlowSpecification;
import co.cask.cdap.api.flow.FlowletConnection;
import co.cask.cdap.api.flow.FlowletDefinition;
import co.cask.cdap.api.flow.flowlet.Flowlet;
import co.cask.cdap.internal.UserErrors;
import co.cask.cdap.internal.UserMessages;
import co.cask.cdap.internal.flow.DefaultFlowSpecification;
import com.clearspring.analytics.util.Lists;
import com.google.common.base.Preconditions;
import com.google.common.collect.Maps;

import java.util.List;
import java.util.Map;

/**
 * Default implementation of {@link FlowConfigurer}.
 */
public class DefaultFlowConfigurer implements FlowConfigurer {

  private String className;
  private String name;
  private String description;
  private Map<String, FlowletDefinition> flowlets;
  private List<FlowletConnection> connections;

  public DefaultFlowConfigurer(Flow flow) {
    this.className = flow.getClass().getName();
    this.name = flow.getClass().getSimpleName();
    this.description = "";
    this.flowlets = Maps.newHashMap();
    this.connections = Lists.newArrayList();
  }

  @Override
  public void setName(String name) {
    this.name = name;
  }

  @Override
  public void setDescription(String description) {
    this.description = description;
  }

  @Override
  public void addFlowlet(Flowlet flowlet) {
    addFlowlet(flowlet, 1);
  }

  @Override
  public void addFlowlet(Flowlet flowlet, int instances) {
    addFlowlet(null, flowlet);
  }

  @Override
  public void addFlowlet(String name, Flowlet flowlet) {
    addFlowlet(name, flowlet, 1);
  }

  private String getFlowletName(Flowlet flowlet) {
    FlowletDefinition flowletDef = new FlowletDefinition(null, flowlet, 1);
    return flowletDef.getFlowletSpec().getName();
  }

  @Override
  public void addFlowlet(String name, Flowlet flowlet, int instances) {
    Preconditions.checkArgument(flowlet != null, UserMessages.getMessage(UserErrors.INVALID_FLOWLET_NULL));
    FlowletDefinition flowletDef = new FlowletDefinition(name, flowlet, instances);
    String flowletName = flowletDef.getFlowletSpec().getName();
    Preconditions.checkArgument(instances > 0, String.format(UserMessages.getMessage(UserErrors.INVALID_INSTANCES),
                                                             flowletName, instances));
    Preconditions.checkArgument(!flowlets.containsKey(flowletName),
                                UserMessages.getMessage(UserErrors.INVALID_FLOWLET_EXISTS), flowletName);
    flowlets.put(flowletName, flowletDef);
  }

  @Override
  public void connect(Flowlet from, Flowlet to) {
    Preconditions.checkArgument(from != null && to != null, UserMessages.getMessage(UserErrors.INVALID_FLOWLET_NULL));
    connect(getFlowletName(from), getFlowletName(to));
  }

  @Override
  public void connect(String from, String to) {
    Preconditions.checkArgument(from != null && to != null, UserMessages.getMessage(UserErrors.INVALID_FLOWLET_NULL));
    Preconditions.checkArgument(flowlets.containsKey(from) && flowlets.containsKey(to),
                                UserMessages.getMessage(UserErrors.INVALID_FLOWLET_NAME));
    connections.add(new FlowletConnection(FlowletConnection.Type.FLOWLET, from, to));
  }

  @Override
  public void connect(Flowlet from, String to) {
    Preconditions.checkArgument(from != null, UserMessages.getMessage(UserErrors.INVALID_FLOWLET_NULL));
    connect(getFlowletName(from), to);
  }

  @Override
  public void connect(String from, Flowlet to) {
    Preconditions.checkArgument(to != null, UserMessages.getMessage(UserErrors.INVALID_FLOWLET_NULL));
    connect(from, getFlowletName(to));
  }

  @Override
  public void connectStream(String stream, Flowlet flowlet) {
    Preconditions.checkArgument(flowlet != null, UserMessages.getMessage(UserErrors.INVALID_FLOWLET_NULL));
    connectStream(stream, getFlowletName(flowlet));
  }

  @Override
  public void connectStream(String stream, String flowlet) {
    Preconditions.checkArgument(stream != null, UserMessages.getMessage(UserErrors.INVALID_STREAM_NAME));
    Preconditions.checkArgument(flowlet != null, UserMessages.getMessage(UserErrors.INVALID_FLOWLET_NULL));
    Preconditions.checkArgument(flowlets.containsKey(flowlet),
                                UserMessages.getMessage(UserErrors.INVALID_FLOWLET_NAME));
    connections.add(new FlowletConnection(FlowletConnection.Type.STREAM, stream, flowlet));
  }

  public FlowSpecification createSpecification() {
    return new DefaultFlowSpecification(className, name, description, flowlets, connections);
  }
}

@@ -1069,39 +1069,39 @@
 com.
-clearspring.analytics.util.List
+google.common.base.Precondition
 s;%0Ai
@@ -1124,33 +1124,28 @@
 .common.
-base.Precondition
+collect.List
 s;%0Aimpor

Use the correct Lists.