import bsh.*;
import java.util.regex.Pattern;
import java.io.FileInputStream;
import java.io.InputStreamReader;
import org.codehaus.plexus.util.StringUtils;
import org.apache.maven.plugin.descriptor.Parameter;
import org.apache.maven.plugin.descriptor.InvalidPluginDescriptorException;

// only on start of line
this.tag = "\\r?\\n\\s*\\*?\\s*@(\\w+)";
// zero width lookahead to next tag or end of comment
this.tagOrEndComment = "(?=" + tag + "|\\*/)";
this.commentTextPattern = Pattern.compile( "(?s)/\\*\\*(.*?)" + tagOrEndComment );
this.tagsPattern = Pattern.compile( "(?s)" + tag + "\\s*(.*?)" + tagOrEndComment );
this.descriptionPattern = Pattern.compile( "(?s)\\r?\\n\\s*\\*" );
this.typePattern = Pattern.compile( "type\\s*=\\s*\"(.*?)\"" );
this.expressionPattern = Pattern.compile( "expression\\s*=\\s*\"(.*?)\"" );
this.defaultValuePattern = Pattern.compile( "default-value\\s*=\\s*\"(.*?)\"" );
this.phasePattern = Pattern.compile( "phase\\s*=\\s*\"(.*?)\"" );
this.goalPattern = Pattern.compile( "goal\\s*=\\s*\"(.*?)\"" );
this.lifecyclePattern = Pattern.compile( "lifecycle\\s*=\\s*\"(.*?)\"" );
this.rolePattern = Pattern.compile( "role\\s*=\\s*\"(.*?)\"" );
this.roleHintPattern = Pattern.compile( "roleHint\\s*=\\s*\"(.*?)\"" );

setAccessibility( true );

createParameter( text, method )
{
    if ( method.startsWith( "set" ) )
    {
        this.name = StringUtils.uncapitalise( method.substring( 3 ) );
        this.desc = getDescription( text );
        this.tags = getTags( text );

        this.parameter = new Parameter();
        parameter.setName( name );
        parameter.setDescription( desc );
        parameter.setRequired( tags.containsKey( "required" ) );
        parameter.setEditable( !tags.containsKey( "readonly" ) );
        this.deprecation = tags.get( "deprecated" );
        if ( deprecation != null )
        {
            parameter.setDeprecated( deprecation );
        }
        this.alias = tags.get( "alias" );
        if ( alias != null )
        {
            parameter.setAlias( alias );
        }
        this.value = tags.get( "parameter" );
        if ( value != null )
        {
            m = typePattern.matcher( value );
            if ( m.find() )
            {
                parameter.setType( m.group( 1 ) );
            }
            else
            {
                parameter.setType( "java.lang.Object" );
            }
            m = expressionPattern.matcher( value );
            if ( m.find() )
            {
                parameter.setExpression( m.group( 1 ) );
            }
            m = defaultValuePattern.matcher( value );
            if ( m.find() )
            {
                parameter.setDefaultValue( m.group( 1 ) );
            }
        }
        value = tags.get( "component" );
        if ( value != null )
        {
            m = rolePattern.matcher( value );
            if ( m.find() )
            {
                role = m.group( 1 );
            }
            m = roleHintPattern.matcher( value );
            if ( m.find() )
            {
                roleHint = m.group( 1 );
            }
            else
            {
                roleHint = null;
            }
            parameter.setRequirement( new Requirement( role, roleHint ) );
        }
        return parameter;
    }
    return null;
}

getTags( text )
{
    this.matcher = tagsPattern.matcher( text );
    this.tags = new HashMap();
    while ( matcher.find() )
    {
        this.tagname = matcher.group( 1 );
        this.tagvalue = matcher.group( 2 );
        tags.put( tagname, tagvalue.trim() );
    }
    return tags;
}

getDescription( text )
{
    this.matcher = commentTextPattern.matcher( text );
    if ( matcher.find() )
    {
        this.input = matcher.group( 1 );
        return descriptionPattern.matcher( input ).replaceAll( "" ).trim();
    }
    else
    {
        return "";
    }
}

extract( file, encoding, mojoDescriptor )
{
    this.parser = new Parser( new InputStreamReader( new FileInputStream( file ), encoding ) );
    parser.setRetainComments( true );

    this.lastNode = null;
    this.firstComment = null;
    while ( !parser.Line() )
    {
        this.node = parser.popNode();

        if ( node instanceof BSHFormalComment && firstComment == null )
        {
            firstComment = node;
        }

        if ( node instanceof BSHMethodDeclaration )
        {
            if ( lastNode instanceof BSHFormalComment )
            {
                this.text = lastNode.text;

                this.method = node.name;

                this.parameter = createParameter( text, method );
                if ( parameter != null )
                {
                    if ( "${reports}".equals( parameter.getExpression() ) )
                    {
                        mojoDescriptor.setRequiresReports( true );
                    }
                    mojoDescriptor.addParameter( parameter );
                }

                if ( firstComment == lastNode )
                {
                    firstComment = null;
                }
            }
        }
        lastNode = node;
    }
    if ( firstComment != null )
    {
        this.text = firstComment.text;

        mojoDescriptor.setDescription( getDescription( text ) );
        this.tags = getTags( text );
        mojoDescriptor.setGoal( tags.get( "goal" ) );
        mojoDescriptor.setPhase( tags.get( "phase" ) );
        this.value = tags.get( "requiresDependencyResolution" );
        // TODO: share with java extractor
        if ( value == null || value.length() == 0 )
        {
            value = "runtime";
        }
        mojoDescriptor.setDependencyResolutionRequired( value );

        mojoDescriptor.setProjectRequired( tags.containsKey( "requiresProject" ) );
        mojoDescriptor.setOnlineRequired( tags.containsKey( "requiresOnline" ) );

        this.value = tags.get( "execute" );
        if ( value != null )
        {
            m = phasePattern.matcher( value );
            if ( m.find() )
            {
                mojoDescriptor.setExecutePhase( m.group( 1 ) );
            }

            m = goalPattern.matcher( value );
            if ( m.find() )
            {
                mojoDescriptor.setExecuteGoal( m.group( 1 ) );
            }

            if ( mojoDescriptor.getExecutePhase() == null || mojoDescriptor.getExecuteGoal() == null )
            {
                throw new InvalidPluginDescriptorException( "@execute must have a phase or goal" );
            }

            if ( mojoDescriptor.getExecutePhase() != null && mojoDescriptor.getExecuteGoal() != null )
            {
                throw new InvalidPluginDescriptorException( "@execute must have only one of a phase or goal" );
            }

            m = lifecyclePattern.matcher( value );
            if ( m.find() )
            {
                mojoDescriptor.setExecuteLifecycle( m.group( 1 ) );
                if ( mojoDescriptor.getExecuteGoal() != null )
                {
                    throw new InvalidPluginDescriptorException( "@execute lifecycle requires a phase instead of a goal" );
                }
            }
        }
    }
}

extract( file, encoding, mojoDescriptor );
