/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.apache.sling.slingstart.model.txt;

import java.io.IOException;
import java.io.LineNumberReader;
import java.io.Reader;

import org.apache.sling.slingstart.model.SSMArtifact;
import org.apache.sling.slingstart.model.SSMConfiguration;
import org.apache.sling.slingstart.model.SSMDeliverable;
import org.apache.sling.slingstart.model.SSMFeature;


public class TXTSSMModelReader {

    /**
     * Reads the deliverable file
     * The reader is not closed.
     * @throws IOException
     */
    public static SSMDeliverable read(final Reader reader)
    throws IOException {
        final SSMDeliverable model = new SSMDeliverable();
        final LineNumberReader lnr = new LineNumberReader(reader);
        String line;
        while ( (line = lnr.readLine()) != null ) {
            if ( ignore(line) ) {
                continue;
            }

            // Command must start with a verb, optionally followed
            // by properties
            if (!isVerb(line)) {
                throw new IOException("Expecting verb, current line is " + line);
            }

            // Parse verb and qualifier from first line
            final String [] firstLine= line.split(" ");
            final String verb = firstLine[0];
            final StringBuilder qualifier = new StringBuilder();
            for(int i=1; i < firstLine.length; i++) {
                if (qualifier.length() > 0) {
                    qualifier.append(' ');
                }
                qualifier.append(firstLine[i]);
            }

            // Parse properties from optional indented lines
            // that follow verb line
            StringBuilder props = null;
            do {
                line = lnr.readLine();
                if (line != null && !isVerb(line)) {
                    if (props == null) {
                        props = new StringBuilder();
                    }
                    addProperty(props, line);
                }
            } while ( line != null && !isVerb(line));

            if ( "classpath".equals("verb") ) {
                final SSMFeature boot = model.getOrCreateFeature(new String[] {SSMFeature.RUN_MODE_BOOT});
                final SSMArtifact artifact = SSMArtifact.fromMvnUrl(qualifier.toString());
                boot.getOrCreateStartLevel(0).artifacts.add(artifact);
            } else if ( "bundle".equals(verb) ) {
                final SSMFeature feature = model.getOrCreateFeature(null);
                final SSMArtifact artifact = SSMArtifact.fromMvnUrl(qualifier.toString());
                feature.getOrCreateStartLevel(0).artifacts.add(artifact);
            } else if ( "configuration".equals(verb) ) {
                final SSMFeature feature = model.getOrCreateFeature(null);
                final SSMConfiguration config = new SSMConfiguration();
                if ( props != null ) {
                    config.properties = props.toString();
                }
                feature.configurations.add(config);
            }
        }

        return model;
    }

    private static boolean ignore(final String line) {
        return line.trim().length() == 0 || line.startsWith("#");
    }

    private static boolean isVerb(final String line) {
        return line.length() > 0 && !Character.isWhitespace(line.charAt(0));
    }

   private static void addProperty(final StringBuilder builder, final String line)
   throws IOException {
        final int equalsPos = line.indexOf('=');
        final String key = line.substring(0, equalsPos).trim();
        final String value = line.substring(equalsPos + 1).trim();
        if (key.trim().isEmpty() || value.trim().isEmpty() ) {
            throw new IOException("Invalid property line [" + line + "]");
        }

        builder.append(key);
        builder.append('=');
        builder.append(value);
        builder.append('\n');
    }
}



@@ -927,16 +927,39 @@
 .Reader;
+%0Aimport java.util.UUID;
 %0A%0Aimport
@@ -1211,16 +1211,93 @@
 ader %7B%0A%0A
+    public static final String FELIX_FORMAT_SUFFIX = %22FORMAT:felix.config%22;%0A%0A
     /**%0A
@@ -2172,23 +2172,21 @@
 Builder 
-qualifi
+build
 er = new
@@ -2277,23 +2277,21 @@
     if (
-qualifi
+build
 er.lengt
@@ -2313,39 +2313,37 @@
                 
-qualifi
+build
 er.append(' ');%0A
@@ -2376,23 +2376,21 @@
         
-qualifi
+build
 er.appen
@@ -2411,32 +2411,89 @@
 );%0A            %7D
+%0A            final String qualifier = builder.toString();
 %0A%0A            //
@@ -3188,35 +3188,24 @@
 rl(qualifier
-.toString()
 );%0A         
@@ -3468,27 +3468,16 @@
 ualifier
-.toString()
 );%0A     
@@ -3576,23 +3576,16 @@
  %22config
-uration
 %22.equals
@@ -3741,16 +3741,1101 @@
 ation();
+%0A                boolean felixFormat = false;%0A                if (qualifier.endsWith(FELIX_FORMAT_SUFFIX)) %7B%0A                    felixFormat = true;%0A                    config.pid = qualifier.split(%22 %22)%5B0%5D.trim();%0A                %7D else %7B%0A                    config.pid = qualifier;%0A                %7D%0A                if ( props != null ) %7B%0A                    config.properties = props.toString();%0A                %7D%0A                feature.configurations.add(config);%0A            %7D else if ( %22config.factory%22.equals(verb) ) %7B%0A                final SSMFeature feature = model.getOrCreateFeature(null);%0A                final SSMConfiguration config = new SSMConfiguration();%0A                boolean felixFormat = false;%0A                if (qualifier.endsWith(FELIX_FORMAT_SUFFIX)) %7B%0A                    felixFormat = true;%0A                    config.factoryPid = qualifier.split(%22 %22)%5B0%5D.trim();%0A                %7D else %7B%0A                    config.factoryPid = qualifier;%0A                %7D%0A                // create unique alias%0A                config.pid = UUID.randomUUID().toString();%0A
 %0A       

Add simple txt parser