/**
   * Assembles the Plan of the Pairwise Shortest Paths example Pact program. The program computes
   * one iteration of the Pairwise Shortest Paths algorithm.
   *
   * <p>For the first iteration, two input formats can be chosen: 1) RDF triples with foaf:knows
   * predicates 2) Text-serialized paths (see PathInFormat and PathOutFormat)
   *
   * <p>To choose 1) set the forth parameter to "true". If set to "false" 2) will be used.
   */
  @Override
  public Plan getPlan(String... args) {

    // parse job parameters
    int numSubTasks = (args.length > 0 ? Integer.parseInt(args[0]) : 1);
    String paths = (args.length > 1 ? args[1] : "");
    String output = (args.length > 2 ? args[2] : "");
    boolean rdfInput = (args.length > 3 ? Boolean.parseBoolean(args[3]) : false);

    FileDataSource pathsInput;

    if (rdfInput) {
      pathsInput = new FileDataSource(new RDFTripleInFormat(), paths, "RDF Triples");
    } else {
      pathsInput = new FileDataSource(new PathInFormat(), paths, "Paths");
    }
    pathsInput.setDegreeOfParallelism(numSubTasks);

    JoinOperator concatPaths =
        JoinOperator.builder(new ConcatPaths(), StringValue.class, 0, 1)
            .name("Concat Paths")
            .build();

    concatPaths.setDegreeOfParallelism(numSubTasks);

    CoGroupOperator findShortestPaths =
        CoGroupOperator.builder(new FindShortestPath(), StringValue.class, 0, 0)
            .keyField(StringValue.class, 1, 1)
            .name("Find Shortest Paths")
            .build();
    findShortestPaths.setDegreeOfParallelism(numSubTasks);

    FileDataSink result = new FileDataSink(new PathOutFormat(), output, "New Paths");
    result.setDegreeOfParallelism(numSubTasks);

    result.setInput(findShortestPaths);
    findShortestPaths.setFirstInput(pathsInput);
    findShortestPaths.setSecondInput(concatPaths);
    concatPaths.setFirstInput(pathsInput);
    concatPaths.setSecondInput(pathsInput);

    return new Plan(result, "Pairwise Shortest Paths");
  }