public class AttributionInfo : Object {
    // Picture width
    public int64 width;
    
    // Picture height
    public int64 height;

    public static AttributionInfo from_variant(Variant variant) {
        var attribution_info = new AttributionInfo();

        VariantDict dict = new VariantDict(variant);
        attribution_info.width = dict.lookup_value("width", VariantType.INT32)?.get_int32() ?? 0;
        attribution_info.height = dict.lookup_value("height", VariantType.INT32)?.get_int32() ?? 0;

        return attribution_info;
    }
}

public class AttachmentMetadata : Object {
    public AttributionInfo? attribution_info = null;

    public static AttachmentMetadata from_variant(Variant variant) {
        var metadata = new AttachmentMetadata();
        
        VariantDict dict = new VariantDict(variant);
        metadata.attribution_info = AttributionInfo.from_variant(dict.lookup_value("attribution_info", VariantType.DICTIONARY));

        return metadata;
    }
}

public class AttachmentInfo : Object {
    public string? path;
    public string? preview_path;
    public bool? downloaded;
    public bool? preview_downloaded;

    public AttachmentInfo(string? path, string? preview_path, bool? downloaded, bool? preview_downloaded) {
        this.path = path;
        this.preview_path = preview_path;
        this.downloaded = downloaded;
        this.preview_downloaded = preview_downloaded;
    }
}

public class Attachment : Object {
    public string guid = "";
    public string path = "";
    public string preview_path = "";
    public bool downloaded = false;
    public bool preview_downloaded = false;
    public AttachmentMetadata? metadata;

    public Attachment(string guid, AttachmentMetadata? metadata) {
        this.guid = guid;
        this.metadata = metadata;
    }

    public Attachment.from_variant(Variant variant) {
        VariantIter iter;
        variant.get("a{sv}", out iter);
        
        string key;
        Variant val;
        while (iter.next("{sv}", out key, out val)) {
            switch (key) {
                case "guid":
                    this.guid = val.get_string();
                    break;
                case "path":
                    this.path = val.get_string();
                    break;
                case "preview_path":
                    this.preview_path = val.get_string();
                    break;
                case "downloaded":
                    this.downloaded = val.get_boolean();
                    break;
                case "preview_downloaded":
                    this.preview_downloaded = val.get_boolean();
                    break;
                case "metadata":
                    this.metadata = AttachmentMetadata.from_variant(val);
                    break;
            }
        }
    }
}
