package foam.lib.json;

import foam.core.*;
import foam.lib.parse.*;

public class ExprParser extends foam.lib.parse.ProxyParser {
  public ExprParser() {
    super(new Alt(
                  new Parser() {
                    private Parser delegate = new Seq0(new Whitespace(),
                                                       new Literal("{"),
                                                       new Whitespace(),
                                                       new KeyParser("class"),
                                                       new Whitespace(),
                                                       new Literal(":"),
                                                       new Whitespace(),
                                                       new Literal("\"__Property__\""),
                                                       new Whitespace(),
                                                       new Literal(","),
                                                       new Whitespace(),
                                                       new KeyParser("source"),
                                                       new Whitespace(),
                                                       new Literal(":"),
                                                       new Whitespace(),
                                                       new Parser() {
                        private Parser delegate = new StringParser();
                        public PStream parse(PStream ps, ParserContext x) {
                          ps = delegate.parse(ps, x);
                          if ( ps != null ) {
                            x.set("classId", ps.value());
                          }
                          return ps;
                        }
                      },
                                                       new Whitespace(),
                                                       new Literal(","),
                                                       new Whitespace(),
                                                       new KeyParser("name"),
                                                       new Literal(":"),
                                                       new Whitespace(),
                                                       new Parser() {
                                                         private Parser delegate = new StringParser();
                                                         public PStream parse(PStream ps, ParserContext x) {
                                                           ps = delegate.parse(ps, x);
                                                           if ( ps != null ) {
                                                             x.set("propName", ps.value());
                                                           }
                                                           return ps;
                                                         }
                                                       },
                                                       new Whitespace(),
                                                       new Literal("}"));
                    public PStream parse(PStream ps, ParserContext x) {
                      ps = delegate.parse(ps, x);
                      if ( ps != null ) {
                        Class cls;
                        try {
                          cls = Class.forName((String)x.get("classId"));
                        } catch(ClassNotFoundException e) {
                          throw new RuntimeException(e);
                        }

                        String prop = (String)x.get("propName");
                        // TODO(adamvy): Use the context to resolve the class rather than reflection
                        // TODO(adamvy): Better handle errors.

                        ClassInfo info;
                        try {
                          info = (ClassInfo)cls.getMethod("getOwnClassInfo").invoke(null);
                        } catch(Exception e) {
                          throw new RuntimeException(e);
                        }

                        return ps.setValue(info.getAxiomByName(prop));
                      }
                      return null;
                    }
                  },
                  new FObjectParser()));
  }
}

@@ -1098,14 +1098,17 @@
 er(%22
-source
+forClass_
 %22),%0A
@@ -1677,23 +1677,25 @@
  x.set(%22
-c
+forC
 lass
-Id
+_
 %22, ps.va
@@ -1963,520 +1963,14 @@
 al(%22
-,%22),%0A                                                       new Whitespace(),%0A                                                       new KeyParser(%22name%22),%0A                                                       new Literal(%22:%22),%0A                                                       new Whitespace(),%0A                                                       new Parser() %7B%0A                                                         private Parser delegate = new StringParser();%0A                                     
+%7D%22));%0A
     
@@ -2041,45 +2041,8 @@
 ) %7B%0A
-                                     
     
@@ -2113,154 +2113,51 @@
     
-                                     if ( p
+String forClas
 s 
-!
 = 
-null ) %7B%0A                                                             x.s
+(String)x.g
 et(%22
-propName%22, ps.value()
+forClass_%22
 );%0A 
@@ -2181,376 +2181,70 @@
     
-                                     %7D%0A                                                           return ps;%0A                                                         %7D%0A                                                       %7D,%0A                                                       new Whitespace(),%0A                                                       new Literal(%22%7D
+String classId = forClass.substring(0, forClass.lastIndexOf(%22.
 %22));
@@ -2268,110 +2268,80 @@
     
-public PStream parse(PStream ps, ParserContext x) %7B%0A                      ps = delegate.parse(ps, x
+  String propName = forClass.substring(forClass.lastIndexOf(%22.%22) + 1
 );%0A
+%0A
     
@@ -2493,32 +2493,15 @@
 ame(
-(String)x.get(%22
 classId
-%22)
 );%0A 
@@ -2647,73 +2647,8 @@
  %7D%0A%0A
-                        String prop = (String)x.get(%22propName%22);%0A
     
@@ -3167,16 +3167,20 @@
 ame(prop
+Name
 ));%0A    

Update Java ExprParser for new Property serialization