class MetadataParser {

  public static MetadataRb parse(String content) throws MetadataParseException {
    MetadataRb metadata = new MetadataRb();
    StringReader reader = new StringReader(content);
    Scanner scanner = new Scanner(reader);
    List<String> comments = new ArrayList<>();
    while (scanner.hasNextLine()) {
      boolean found = false;
      String line = scanner.nextLine();
      line = line.trim();
      if (!line.isEmpty()) {
        if (line.startsWith("#")) {
          //It assumes that each comment block belongs to the next definition, it records comments until it finds out 
          //the next item
          comments.add(line);
          found = true;
        }

        //name of the cookbook
        if (!found) {
          Matcher m1 = NAME.matcher(line);
          if (m1.matches()) {
            metadata.setName(m1.group(1));
            found = true;
          }
        }

        //description of the cookbook
        if (!found) {
          Matcher m2 = DESC.matcher(line);
          if (m2.matches()) {
            metadata.setDescription(m2.group(1));
            found = true;
          }
        }

        //version of the cookbook
        if (!found) {
          Matcher m3 = VERSION.matcher(line);
          if (m3.matches()) {
            metadata.setVersion(m3.group(1));
            found = true;
          }
        }

        //recipe is a single line definition
        if (!found) {
          Matcher m4 = RECIPE.matcher(line);
          if (m4.matches()) {
            Recipe r = new Recipe();
            r.setName(m4.group(1));
            r.setDescription(m4.group(3));
            r.parseComments(comments);
            metadata.getRecipes().add(r);
            found = true;
            comments.clear();
          }
        }

        //attribute is multiple line definition
        if (!found) {
          Matcher m5 = ATTR.matcher(line);
          if (m5.matches()) {
            Attribute attr = new Attribute();
            attr.setName(m5.group(1));
            while (line.matches(COMMA_CLOSING_LINE) && scanner.hasNext()) {
              boolean found2 = false;
              line = scanner.nextLine();

              Matcher m6 = ATTR_DISP_NAME.matcher(line);
              if (m6.matches()) {
                attr.setDisplayName(m6.group(1));
                found2 = true;
              }

              if (!found2) {
                Matcher m7 = ATTR_TYPE.matcher(line);
                if (m7.matches()) {
                  attr.setType(m7.group(1));
                  found2 = true;
                }
              }

              if (!found2) {
                Matcher m8 = ATTR_DESC.matcher(line);
                if (m8.matches()) {
                  attr.setDescription(m8.group(1));
                  found2 = true;
                }

              }

              if (!found2) {
                Matcher m92 = ATTR_DEFAULT_ARRAY.matcher(line);
                if (m92.matches()) {
                  String sarr = m92.group(1);
                  Matcher m921 = ATTR_DEFAULT_ARRAY_ITEMS.matcher(sarr);
                  List<String> deflist = new ArrayList<>();
                  while (m921.find()) {
                    String item = m921.group(1);
                    deflist.add(item);
                  }
                  attr.setDefault(deflist);
                  found2 = true;
                }
              }
              
              if (!found2) {
                Matcher m91 = ATTR_DEFAULT_SIMPLE.matcher(line);
                if (m91.matches()) {
                  attr.setDefault(m91.group(1));
                  found2 = true;
                }
              }
              
              if (!found2) {
                Matcher m10 = ATTR_REQUIRED.matcher(line);
                if (m10.matches()) {
                  attr.setRequired(m10.group(1));
                  found2 = true;
                }
              }

              if (!found2) {
                logger.debug(String.format("Urecognized line for attribute in the metadata.rb '%s'", line));
              }
            }
            metadata.getAttributes().add(attr);
            found = true;
          }
        }

        if (!found) {
          logger.debug(String.format("Urecognized line in the metadata.rb '%s'", line));
        }
      } else {
        comments.clear();
      }
    }
    return metadata;
  }

}