/*
 * Copyright (C) 2010 Google 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.google.doclava;

import com.google.clearsilver.jsilver.data.Data;

import java.util.*;

public class TodoFile {

  public static final String MISSING = "No description text";

  public static boolean areTagsUseful(InheritedTags tags) {
    while (tags != null) {
      if (areTagsUseful(tags.tags())) {
        return true;
      }
      tags = tags.inherited();
    }
    return false;
  }

  public static boolean areTagsUseful(TagInfo[] tags) {
    for (TagInfo t : tags) {
      if ("Text".equals(t.name()) && t.text().trim().length() != 0) {
        return true;
      }
      if ("@inheritDoc".equals(t.name())) {
        return true;
      }
    }
    return false;
  }

  public static void setHDF(Data data, String base, SourcePositionInfo pos, String name,
      String descr) {
    data.setValue(base + ".pos", pos.toString());
    data.setValue(base + ".name", name);
    data.setValue(base + ".descr", descr);
  }

  static class PackageStats {
    String name;
    public int total;
    public int errors;
  }

  public static String percent(int a, int b) {
    return "" + Math.round((((b - a) / (float) b)) * 100) + "%";
  }

  public static void writeTodoFile(String filename) {
    Data data = Doclava.makeHDF();
    Doclava.setPageTitle(data, "Missing Documentation");
    TreeMap<String, PackageStats> packageStats = new TreeMap<String, PackageStats>();

    ClassInfo[] classes = Converter.rootClasses();
    Arrays.sort(classes);

    int classIndex = 0;

    for (ClassInfo cl : classes) {
      if (cl.isHiddenOrRemoved()){
        continue;
      }

      String classBase = "classes." + classIndex;

      String base = classBase + ".errors.";
      int errors = 0;
      int total = 1;

      if (!areTagsUseful(cl.inlineTags())) {
        setHDF(data, base + errors, cl.position(), "&lt;class comment&gt;", MISSING);
        errors++;
      }


      for (MethodInfo m : cl.constructors()) {
        boolean good = true;
        total++;
        if (m.checkLevel()) {
          if (!areTagsUseful(m.inlineTags())) {
            setHDF(data, base + errors, m.position(), m.prettySignature(), MISSING);
            good = false;
          }
        }
        if (!good) {
          errors++;
        }
      }

      for (MethodInfo m : cl.selfMethods()) {
        boolean good = true;
        total++;
        if (m.checkLevel()) {
          if (!areTagsUseful(m.inlineTags())) {
            setHDF(data, base + errors, m.position(), m.name() + m.prettySignature(), MISSING);
            good = false;
          }
        }
        if (!good) {
          errors++;
        }
      }


      for (FieldInfo f : cl.enumConstants()) {
        boolean good = true;
        total++;
        if (f.checkLevel()) {
          if (!areTagsUseful(f.inlineTags())) {
            setHDF(data, base + errors, f.position(), f.name(), MISSING);
            good = false;
          }
        }
        if (!good) {
          errors++;
        }
      }

      for (FieldInfo f : cl.selfFields()) {
        boolean good = true;
        total++;
        if (f.checkLevel()) {
          if (!areTagsUseful(f.inlineTags())) {
            setHDF(data, base + errors, f.position(), f.name(), MISSING);
            good = false;
          }
        }
        if (!good) {
          errors++;
        }
      }

      if (errors > 0) {
        data.setValue(classBase + ".qualified", cl.qualifiedName());
        data.setValue(classBase + ".errorCount", "" + errors);
        data.setValue(classBase + ".totalCount", "" + total);
        data.setValue(classBase + ".percentGood", percent(errors, total));
      }

      PackageInfo pkg = cl.containingPackage();
      String pkgName = pkg != null ? pkg.name() : "";
      PackageStats ps = packageStats.get(pkgName);
      if (ps == null) {
        ps = new PackageStats();
        ps.name = pkgName;
        packageStats.put(pkgName, ps);
      }
      ps.total += total;
      ps.errors += errors;

      classIndex++;
    }

    int allTotal = 0;
    int allErrors = 0;

    int i = 0;
    for (PackageStats ps : packageStats.values()) {
      data.setValue("packages." + i + ".name", "" + ps.name);
      data.setValue("packages." + i + ".errorCount", "" + ps.errors);
      data.setValue("packages." + i + ".totalCount", "" + ps.total);
      data.setValue("packages." + i + ".percentGood", percent(ps.errors, ps.total));

      allTotal += ps.total;
      allErrors += ps.errors;

      i++;
    }

    data.setValue("all.errorCount", "" + allErrors);
    data.setValue("all.totalCount", "" + allTotal);
    data.setValue("all.percentGood", percent(allErrors, allTotal));

    ClearPage.write(data, "todo.cs", filename, true);
  }
}
