content: package org.alloytools.alloy.lsp.provider;
  
  import java.io.File;
  import java.util.ArrayList;
  import java.util.Date;
  import java.util.List;
  import java.util.Random;
  
  import edu.mit.csail.sdg.alloy4.Err;
  import edu.mit.csail.sdg.alloy4.ErrorFatal;
  import edu.mit.csail.sdg.alloy4.OurDialog;
  import edu.mit.csail.sdg.alloy4.Util;
  import edu.mit.csail.sdg.ast.ExprVar;
  import edu.mit.csail.sdg.ast.Module;
  import edu.mit.csail.sdg.ast.Sig;
  import edu.mit.csail.sdg.ast.Sig.Field;
  import edu.mit.csail.sdg.sim.SimInstance;
  import edu.mit.csail.sdg.sim.SimTuple;
  import edu.mit.csail.sdg.sim.SimTupleset;
  import edu.mit.csail.sdg.translator.A4Solution;
  import edu.mit.csail.sdg.translator.A4Tuple;
  import edu.mit.csail.sdg.translator.A4TupleSet;
  
  public class AlloyAppUtil {
  
      /**
       * This variable caches the result of alloyHome() function call.
       */
      private static String alloyHome = null;
  
      /**
       * Find a temporary directory to store Alloy files; it's guaranteed to be a
       * canonical absolute path.
       */
      public static synchronized String alloyHome() {
          if (alloyHome != null)
              return alloyHome;
          String temp = System.getProperty("java.io.tmpdir");
          if (temp == null || temp.length() == 0)
              OurDialog.fatal(null, "Error. JVM need to specify a temporary directory using java.io.tmpdir property.");
          String username = System.getProperty("user.name");
          File tempfile = new File(temp + File.separatorChar + "alloy4tmp40-" + (username == null ? "" : username));
          tempfile.mkdirs();
          String ans = Util.canon(tempfile.getPath());
          if (!tempfile.isDirectory()) {
              OurDialog.fatal(null, "Error. Cannot create the temporary directory " + ans);
          }
          if (!Util.onWindows()) {
              String[] args = {
                               "chmod", "700", ans
              };
              try {
                  Runtime.getRuntime().exec(args).waitFor();
              } catch (Throwable ex) {
              } // We only intend to make a best effort.
          }
          return alloyHome = ans;
      }
  
      /**
       * Create an empty temporary directory for use, designate it "deleteOnExit",
       * then return it. It is guaranteed to be a canonical absolute path.
       */
      public static String maketemp() {
          Random r = new Random(new Date().getTime());
          while (true) {
              int i = r.nextInt(1000000);
              String dest = AlloyAppUtil.alloyHome() + File.separatorChar + "tmp" + File.separatorChar + i;
              File f = new File(dest);
              if (f.mkdirs()) {
                  f.deleteOnExit();
                  return Util.canon(dest);
              }
          }
      }
  
      /** Converts an A4TupleSet into a SimTupleset object. */
      public static SimTupleset convert(Object object) throws Err {
          if (!(object instanceof A4TupleSet))
              throw new ErrorFatal("Unexpected type error: expecting an A4TupleSet.");
          A4TupleSet s = (A4TupleSet) object;
          if (s.size() == 0)
              return SimTupleset.EMPTY;
          List<SimTuple> list = new ArrayList<SimTuple>(s.size());
          int arity = s.arity();
          for (A4Tuple t : s) {
              String[] array = new String[arity];
              for (int i = 0; i < t.arity(); i++)
                  array[i] = t.atom(i);
              list.add(SimTuple.make(array));
          }
          return SimTupleset.make(list);
      }
  
      /** Converts an A4Solution into a SimInstance object. */
      public static SimInstance convert(Module root, A4Solution ans) throws Err {
          SimInstance ct = new SimInstance(root, ans.getBitwidth(), ans.getMaxSeq());
          for (Sig s : ans.getAllReachableSigs()) {
              if (!s.builtin)
                  ct.init(s, convert(ans.eval(s)));
              for (Field f : s.getFields())
                  if (!f.defined)
                      ct.init(f, convert(ans.eval(f)));
          }
          for (ExprVar a : ans.getAllAtoms())
              ct.init(a, convert(ans.eval(a)));
          for (ExprVar a : ans.getAllSkolems())
              ct.init(a, convert(ans.eval(a)));
          return ct;
      }
  
  
      public interface Func0<T> {
  
          public T call() throws Exception;
      }
  
      public static <T> T uncheckedRun(Func0<T> func) {
          try {
              return func.call();
          } catch (RuntimeException e) {
              throw e;
          } catch (Exception e) {
              throw new RuntimeException(e);
          }
      }
  
  }
  