// Copyright 2014 The Bazel Authors. All rights reserved.
//
// 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.google.devtools.build.lib.graph;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;

/**
 * <p>A simple and inefficient directed graph with the adjacency
 * relation represented as a 2-D bit-matrix. </p>
 *
 * <p> Used as an adjunct to Digraph for performing certain algorithms
 * which are more naturally implemented on this representation,
 * e.g. transitive closure and reduction. </p>
 *
 * <p> Not many operations are supported. </p>
 */
final class Matrix<T> {

  /**
   * Constructs a square bit-matrix, initially empty, with the ith row/column
   * corresponding to the ith element of 'labels', in iteration order.
   *
   * Does not retain a references to 'labels'.
   */
  public Matrix(Set<T> labels) {
    this.N = labels.size();
    this.values = new ArrayList<T>(N);
    this.indices = new HashMap<>();
    this.m = new boolean[N][N];

    for (T label: labels) {
      int idx = values.size();
      values.add(label);
      indices.put(label, idx);
    }
  }

  /**
   * Constructs a matrix from the set of logical values specified.  There is
   * one row/column for each node in the graph, and the entry matrix[i,j] is
   * set iff there is an edge in 'graph' from the node labelled values[i] to
   * the node labelled values[j].
   */
  public Matrix(Digraph<T> graph) {
    this(graph.getLabels());

    for (Node<T> nfrom: graph.getNodes()) {
      Integer ifrom = indices.get(nfrom.getLabel());
      for (Node<T> nto: nfrom.getSuccessors()) {
        Integer ito = indices.get(nto.getLabel());
        m[ifrom][ito] = true;
      }
    }
  }

  /**
   * The size of one side of the matrix.
   */
  private final int N;

  /**
   * The logical values associated with each row/column.
   */
  private final List<T> values;

  /**
   * The mapping from logical values to row/column index.
   */
  private final Map<T, Integer>  indices;

  /**
   * The bit-matrix itself.
   * m[from][to] indicates an edge from-->to.
   */
  private final boolean[][] m;

  @Override
  public String toString() {
    StringBuilder sb = new StringBuilder();
    for (int ii = 0; ii < N; ++ii) {
      for (int jj = 0; jj < N; ++jj) {
        sb.append(m[ii][jj] ? '1' : '0');
      }
      sb.append(' ').append(values.get(ii)).append('\n');
    }
    return sb.toString();
  }

}
