package org.reactivecouchbase.json;

import com.google.common.collect.Lists;
import org.reactivecouchbase.common.Functionnal;

import java.io.Serializable;
import java.util.Collections;
import java.util.List;

public abstract class JsValue implements Serializable {
    public <T extends JsValue> Iterable<T> extractAs(Class<T> clazz) {
        if (is(clazz)) {
            return Collections.singletonList(clazz.cast(this));
        }
        return Collections.emptyList();
    }
    public <T extends JsValue> boolean is(Class<T> clazz) {
        return clazz.isAssignableFrom(this.getClass());
    }
    public abstract String toJsonString();
    public <T> T as(Class<T> clazz, Reader<T> reader) {
        return reader.read(this).getOpt().get();
    }
    public <T> T as(Class<T> clazz) {
        return asOpt(clazz).get();
    }
    public <T> Functionnal.Option<T> asOpt(Class<T> clazz, Reader<T> reader) {
        return reader.read(this).getOpt();
    }
    public <T> Functionnal.Option<T> asOpt(Class<T> clazz) {
        for (Reader<T> reader : DefaultReaders.getReader(clazz)) {
            return reader.read(this).getOpt();
        }
        return Functionnal.Option.none();
    }
    public <T> JsResult<T> read(Class<T> clazz) {
        for (Reader<T> reader : DefaultReaders.getReader(clazz)) {
            return reader.read(this);
        }
        return new JsError<T>(new IllegalStateException("Cannot find reader for type " + clazz.getName()));
    }
    public <T> JsResult<T> read(Reader<T> reader) {
        return reader.read(this);
    }
    public <T> JsResult<T> validate(Reader<T> reader) {
        return reader.read(this);
    }
    public <A extends JsValue> JsResult<A> transform(Reader<A> reader) {
        return reader.read(this);
    }
    public Boolean exists(String field) {
        return false;
    }
    public JsValue field(String field) {
        return JsonLib.JSUNDEFINED_INSTANCE;
    }
    public Functionnal.Option<JsValue> fieldAsOpt(String field) {
        return Functionnal.Option.none();
    }
    public List<JsValue> fields(String fieldName) {
        return Lists.newArrayList();
    }
    public JsValue _(String field) {
        return this.field(field);
    }
    public List<JsValue> __(String fieldName) {
        return this.fields(fieldName);
    }
    public JsValue get(int idx) {
        return JsonLib.JSUNDEFINED_INSTANCE;
    }
}
@@ -259,16 +259,17 @@
 zable %7B%0A
+%0A
     publ
@@ -468,32 +468,33 @@
 tyList();%0A    %7D%0A
+%0A
     public %3CT ex
@@ -599,26 +599,20 @@
 ;%0A    %7D%0A
- 
+%0A
    
-public
  abstrac
@@ -632,24 +632,25 @@
 onString();%0A
+%0A
     public %3C
@@ -740,32 +740,33 @@
 ().get();%0A    %7D%0A
+%0A
     public %3CT%3E T
@@ -820,32 +820,33 @@
 z).get();%0A    %7D%0A
+%0A
     public %3CT%3E F
@@ -949,32 +949,33 @@
 getOpt();%0A    %7D%0A
+%0A
     public %3CT%3E F
@@ -1183,32 +1183,33 @@
 n.none();%0A    %7D%0A
+%0A
     public %3CT%3E J
@@ -1463,32 +1463,33 @@
 Name()));%0A    %7D%0A
+%0A
     public %3CT%3E J
@@ -1556,32 +1556,33 @@
 ad(this);%0A    %7D%0A
+%0A
     public %3CT%3E J
@@ -1653,32 +1653,33 @@
 ad(this);%0A    %7D%0A
+%0A
     public %3CA ex
@@ -1767,32 +1767,33 @@
 ad(this);%0A    %7D%0A
+%0A
     public Boole
@@ -1838,32 +1838,33 @@
 rn false;%0A    %7D%0A
+%0A
     public JsVal
@@ -1931,32 +1931,33 @@
 INSTANCE;%0A    %7D%0A
+%0A
     public Funct
@@ -2046,32 +2046,33 @@
 n.none();%0A    %7D%0A
+%0A
     public List%3C
@@ -2142,32 +2142,33 @@
 ayList();%0A    %7D%0A
+%0A
     public JsVal
@@ -2220,32 +2220,33 @@
 d(field);%0A    %7D%0A
+%0A
     public List%3C
@@ -2316,22 +2316,23 @@
 dName);%0A
-
     %7D%0A
+%0A
     publ

Remove visibility