// Copyright (C) 2015 The Android Open Source Project
//
// 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.gerrit.server.git;

import org.slf4j.Logger;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.StringReader;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class TabFile {
  public interface Parser {
    String parse(String str);
  }

  public static Parser TRIM = new Parser() {
    @Override
    public String parse(String str) {
       return str.trim();
    }
  };

  protected static class Row {
    public String left;
    public String right;

    public Row(String left, String right) {
      this.left = left;
      this.right = right;
    }
  }

  protected static List<Row> parse(String text, String filename, Parser left,
      Parser right, ValidationError.Sink errors) throws IOException {
    List<Row> rows = new ArrayList<>();
    BufferedReader br = new BufferedReader(new StringReader(text));
    String s;
    for (int lineNumber = 1; (s = br.readLine()) != null; lineNumber++) {
      if (s.isEmpty() || s.startsWith("#")) {
        continue;
      }

      int tab = s.indexOf('\t');
      if (tab < 0) {
        errors.error(new ValidationError(filename, lineNumber,
            "missing tab delimiter"));
        continue;
      }

      Row row = new Row(s.substring(0, tab), s.substring(tab + 1));
      rows.add(row);

      if (left != null) {
        row.left = left.parse(row.left);
      }
      if (right != null) {
        row.right = right.parse(row.right);
      }
    }
    return rows;
  }

  protected static Map<String, String> toMap(List<Row> rows) {
    Map<String, String> map = new HashMap<>(rows.size());
    for (Row row : rows) {
      map.put(row.left, row.right);
    }
    return map;
  }

  protected static String asText(String left, String right,
      Map<String, String> entries) {
    if (entries.isEmpty()) {
      return null;
    }

    List<Row> rows = new ArrayList<>(entries.size());
    for (String key : sort(entries.keySet())) {
      rows.add(new Row(key, entries.get(key)));
    }
    return asText(left, right, rows);
  }

  protected static String asText(String left, String right, List<Row> rows) {
    if (rows.isEmpty()) {
      return null;
    }

    left = "# " + left;
    int leftLen = left.length();
    for (Row row : rows) {
      leftLen = Math.max(leftLen, row.left.length());
    }

    StringBuilder buf = new StringBuilder();
    buf.append(pad(leftLen, left));
    buf.append('\t');
    buf.append(right);
    buf.append('\n');

    buf.append('#');
    buf.append('\n');

    for (Row row : rows) {
      buf.append(pad(leftLen, row.left));
      buf.append('\t');
      buf.append(row.right);
      buf.append('\n');
    }
    return buf.toString();
  }

  protected static <T extends Comparable<? super T>> List<T> sort(Collection<T> m) {
    ArrayList<T> r = new ArrayList<>(m);
    Collections.sort(r);
    return r;
  }

  protected static String pad(int len, String src) {
    if (len <= src.length()) {
      return src;
    }

    StringBuilder r = new StringBuilder(len);
    r.append(src);
    while (r.length() < len) {
      r.append(' ');
    }
    return r.toString();
  }

  public static ValidationError.Sink createLoggerSink(String file, Logger log) {
    return ValidationError.createLoggerSink("Error parsing file " + file + ": ",
        log);
  }
}
