/*
 * Copyright 2013-present Facebook, 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 com.facebook.buck.ocaml;

import com.facebook.buck.graph.MutableDirectedGraph;
import com.facebook.buck.graph.TopologicalSort;
import com.google.common.base.Function;
import com.google.common.base.Preconditions;
import com.google.common.base.Predicate;
import com.google.common.base.Predicates;
import com.google.common.base.Splitter;
import com.google.common.collect.FluentIterable;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;

import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.List;

import javax.annotation.Nullable;

/**
 * Parse output of ocamldep tool and build dependency graph of ocaml source files (*.ml & *.mli)
 */
public class OCamlDependencyGraphGenerator {
  private static final String OCAML_SOURCE_AND_DEPS_SEPARATOR = ":";
  private static final String OCAML_DEPS_SEPARATOR = " ";
  private static final String LINE_SEPARATOR = System.getProperty("line.separator");

  @Nullable
  private MutableDirectedGraph<String> graph;

  public ImmutableList<String> generate(String depToolOutput) {
    parseDependencies(depToolOutput);
    Preconditions.checkNotNull(graph);
    final ImmutableList<String> sortedDeps = TopologicalSort.sort(
        graph, Predicates.<String>alwaysTrue());

    return FluentIterable.from(sortedDeps).transform(
        new Function<String, String>() {
          @Override
          public String apply(String input) {
            return input.replaceAll(
                OCamlCompilables.OCAML_CMX_REGEX, OCamlCompilables.OCAML_ML).replaceAll(
                OCamlCompilables.OCAML_CMI_REGEX, OCamlCompilables.OCAML_MLI);
          }
        }).toList();
  }

  private String replaceObjExtWithSourceExt(String name) {
    return name.replaceAll(
          OCamlCompilables.OCAML_CMX_REGEX,
          OCamlCompilables.OCAML_ML)
        .replaceAll(
            OCamlCompilables.OCAML_CMI_REGEX,
            OCamlCompilables.OCAML_MLI);
  }
  public ImmutableMap<Path, ImmutableList<Path>> generateDependencyMap(
      String depString) {
    ImmutableMap.Builder<Path, ImmutableList<Path>> mapBuilder = ImmutableMap.builder();
    Iterable<String> lines = Splitter.on(LINE_SEPARATOR).split(depString);
    for (String line : lines) {
      List<String> sourceAndDeps = Splitter.on(OCAML_SOURCE_AND_DEPS_SEPARATOR)
          .trimResults().splitToList(line);
      if (sourceAndDeps.size() >= 1) {
        String source = replaceObjExtWithSourceExt(sourceAndDeps.get(0));
        if (source.endsWith(OCamlCompilables.OCAML_ML) ||
            source.endsWith(OCamlCompilables.OCAML_MLI)) {
          FluentIterable<Path> dependencies = FluentIterable
              .from(
                Splitter.on(OCAML_DEPS_SEPARATOR)
                  .trimResults().splitToList(sourceAndDeps.get(1)))
              .filter(new Predicate<String>() {
                        @Override
                        public boolean apply(String input) {
                          return !input.isEmpty();
                        }
                      })
              .transform(
                  new Function<String, Path>() {
                    @Override
                    public Path apply(String input) {
                      return Paths.get(replaceObjExtWithSourceExt(input));
                    }
                  });
          mapBuilder.put(
              Paths.get(source),
              ImmutableList.copyOf(dependencies));
        }
      }
    }
    return mapBuilder.build();
  }

  private void parseDependencies(String stdout) {
    graph = new MutableDirectedGraph<>();
    Iterable<String> lines = Splitter.on(LINE_SEPARATOR).split(stdout);

    for (String line : lines) {
      List<String> sourceAndDeps = Splitter.on(OCAML_SOURCE_AND_DEPS_SEPARATOR)
          .trimResults().splitToList(line);
      if (sourceAndDeps.size() >= 1) {
        String source = sourceAndDeps.get(0);
        if (source.endsWith(OCamlCompilables.OCAML_CMX) || source.endsWith(
            OCamlCompilables.OCAML_CMI)) {
          addSourceDeps(sourceAndDeps, source);
        }
      }
    }
  }

  private void addSourceDeps(List<String> sourceAndDeps, String source) {
    Preconditions.checkNotNull(graph);
    graph.addNode(source);
    if (sourceAndDeps.size() >= 2) {
      String deps = sourceAndDeps.get(1);
      if (!deps.isEmpty()) {
        List<String> dependencies = Splitter.on(OCAML_DEPS_SEPARATOR)
            .trimResults().splitToList(deps);
        for (String dep : dependencies) {
          if (!dep.isEmpty()) {
            graph.addEdge(source, dep);
          }
        }
      }
    }
  }
}
