package com.airbnb.aerosolve.core.util;

import com.airbnb.aerosolve.core.FeatureVector;
import lombok.extern.slf4j.Slf4j;

import java.util.Map;
import java.util.Set;

@Slf4j
public class Debug  {
  public static void printDiff(FeatureVector a, FeatureVector b) {
    final Map<String, Set<String>> stringFeaturesA = a.getStringFeatures();
    final Map<String, Set<String>> stringFeaturesB = b.getStringFeatures();
    printDiff(stringFeaturesA, stringFeaturesB);
    final Map<String, Map<String, Double>> floatFeaturesA = a.getFloatFeatures();
    final Map<String, Map<String, Double>> floatFeaturesB = b.getFloatFeatures();
    printFloatDiff(floatFeaturesA, floatFeaturesB);
  }

  private static void printFloatDiff(Map<String, Map<String, Double>> a,
                                     Map<String, Map<String, Double>> b) {
    for (Map.Entry<String, Map<String, Double>> entry : a.entrySet()) {
      String key = entry.getKey();
      Map<String, Double> bSet = b.get(key);
      if (bSet == null) {
        log.info("b miss float family {}", key);
      } else {
        printMapDiff(entry.getValue(), bSet);
      }
    }

    for (Map.Entry<String, Map<String, Double>> entry : b.entrySet()) {
      String key = entry.getKey();
      Map<String, Double> bSet = a.get(key);
      if (bSet == null) {
        log.info("a miss float family {}", key);
      }
    }
  }

  private static void printMapDiff(Map<String, Double> a, Map<String, Double> b) {
    for (Map.Entry<String, Double> entry : a.entrySet()) {
      String key = entry.getKey();
      Double bValue = b.get(key);
      if (bValue == null) {
        log.info("b miss feature {} {}", key, entry.getValue());
      } else {
        if (Math.abs(bValue- entry.getValue()) > 0.01) {
          log.info("feature {} a: {}, b: {}", key, entry.getValue(), bValue);
        }
      }
    }

    for (Map.Entry<String, Double> entry : b.entrySet()) {
      String key = entry.getKey();
      Double bValue = a.get(key);
      if (bValue == null) {
        log.info("a miss feature {} {}", key, entry.getValue());
      }
    }
  }


  public static void printDiff(Map<String, Set<String>> a, Map<String, Set<String>> b) {
    for (Map.Entry<String, Set<String>> entry : a.entrySet()) {
      String key = entry.getKey();
      Set<String> bSet = b.get(key);
      if (bSet == null) {
        log.info("b miss string family {}", key);
      } else {
        printDiff(entry.getValue(), bSet);
      }
    }

    for (Map.Entry<String, Set<String>> entry : b.entrySet()) {
      String key = entry.getKey();
      Set<String> bSet = a.get(key);
      if (bSet == null) {
        log.info("a miss string family {}", key);
      }
    }
  }

  private static void printDiff(Set<String> a, Set<String> b) {
    for(String s : a) {
      if (!b.contains(s)) {
        log.info("b missing {}", s);
      }
    }
    for(String s : b) {
      if (!a.contains(s)) {
        log.info("a missing {}", s);
      }
    }
  }
}

@@ -34,16 +34,58 @@
 .util;%0A%0A
+import com.airbnb.aerosolve.core.Example;%0A
 import c
@@ -158,16 +158,282 @@
 .Slf4j;%0A
+import org.apache.thrift.TDeserializer;%0Aimport org.apache.thrift.TSerializer;%0Aimport org.apache.thrift.protocol.TBinaryProtocol;%0A%0Aimport java.io.FileOutputStream;%0Aimport java.net.URL;%0Aimport java.nio.file.Files;%0Aimport java.nio.file.Path;%0Aimport java.nio.file.Paths;
 %0Aimport 
@@ -3283,11 +3283,1110 @@
    %7D%0A  %7D
+%0A%0A  /*%0A  loadExampleFromResource read example from resources folder, i.e. test/resources%0A  use it on unit test to load example from disk%0A */%0A  public static Example loadExampleFromResource(String name) %7B%0A    URL url = Debug.class.getResource(%22/%22 + name);%0A    try %7B%0A      Path path = Paths.get(url.toURI());%0A      byte%5B%5D bytes = Files.readAllBytes(path);%0A      TDeserializer deserializer = new TDeserializer(new TBinaryProtocol.Factory());%0A      Example example = new Example();%0A      deserializer.deserialize(example, bytes);%0A      return example;%0A    %7D catch (Exception e) %7B%0A      e.printStackTrace();%0A    %7D%0A    assert(false);%0A    return null;%0A  %7D%0A%0A  // Save example to path%0A  // If you hit permission error, touch and chmod the file%0A  public static void saveExample(Example example, String path) %7B%0A    TSerializer serializer = new TSerializer(new TBinaryProtocol.Factory());%0A    try %7B%0A      byte%5B%5D buf = serializer.serialize(example);%0A      FileOutputStream fos = new FileOutputStream(path);%0A      fos.write(buf);%0A      fos.close();%0A    %7D catch (Exception e) %7B%0A      e.printStackTrace();%0A    %7D%0A  %7D
 %0A%7D%0A

add load and save example for debug.