/*******************************************************************************
 * Copyright (c) 21.08.2011 Aaron Digulla.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *    Aaron Digulla - initial API and implementation and/or initial documentation
 *******************************************************************************/
package m4e

import de.pdark.decentxml.*

class PomElement {
    Pom pom
    Element xml
    
    String value( TextNode node ) {
        Element e = xml( node )
        return e == null ? null : e.trimmedText
    }
    
    void value( TextNode node, String text ) {
        Element e = xml( node )
        if( e == null ) {
            if( !text ) {
                return
            }
            
            e = PomUtils.getOrCreate( xml, node.name )
            e.text = text
        } else {
            if( !text ) {
                PomUtils.removeWithIndent( e )
            } else {
                e.text = text
            }
        }
    }
    
    List list( ListNode node ) {
        def result = xml.getChild( node.name )?.getChildren( node.child ).collect {
            new PomElement( pom: this.pom, xml: it )
        }
        
        return result ?: []
    }
    
    Element xml( node ) {
        if( !(node instanceof String ) ) {
            node = node.name
        }
        return xml.getChild( node )
    }
    
    PomElement element( node ) {
        Element child = xml( node )
        
        return child ? new PomElement( xml: child, pom: pom ) : null
    }
    
    void remove() {
        PomUtils.removeWithIndent( xml )
    }
}

class TextNode {
    String name
    String defaultValue
}

class ListNode {
    String name
    String child
}

class Pom extends PomElement {
    
    final static TextNode GROUP_ID = new TextNode( name: 'groupId' )
    final static TextNode ARTIFACT_ID = new TextNode( name: 'artifactId' )
    final static TextNode VERSION = new TextNode( name: 'version' )
    final static TextNode PARENT = new TextNode( name: 'parent' )
    final static TextNode PROPERTIES = new TextNode( name: 'properties' )

    final static String IMPORT_PACKAGE_PROPERTY = 'mt4e.osgi.importPackage'
    final static String EXPORT_PACKAGE_PROPERTY = 'mt4e.osgi.exportPackage'
    final static String IS_SINGLETON_PROPERTY = 'mt4e.osgi.isSingleton'
    
    String source
    
    String key() {
        return "${groupId()}:${artifactId()}:${version()}";
    }
    
    String shortKey() {
        return "${groupId()}:${artifactId()}";
    }
    
    String groupId() {
        String groupId = value( GROUP_ID )
        if( null == groupId ) {
            PomElement parent = element( PARENT )
            groupId = parent.value( GROUP_ID )
        }
        return groupId
    }
    
    String artifactId() {
        return value( ARTIFACT_ID )
    }

    String version() {
        String version = value( VERSION )
        if( null == version ) {
            PomElement parent = element( PARENT )
            version = parent.value( VERSION )
        }
        return version
    }

	public static Pom load( def input ) {
        String source
		if( input instanceof String ) {
            source = "<String>"
			input = new XMLStringSource( input )
		}
		if( input instanceof File ) {
            source = input.absolutePath
			input = new XMLIOSource( input )
		}
		
		XMLParser parser = new XMLParser();
		def doc = parser.parse( input )
		
        def pom = new Pom( doc: doc, source: source )
        pom.init()
		return pom
	}
	
	Document doc;
	
    void init() {
        this.pom = this
        this.xml = doc.getRootElement()
        
        assert 'project' == this.xml.name
    }
    
    List<String> files() {
        File dir = new File( source ).parentFile
        
        String prefix = "${artifactId()}-${version()}"
        
        Set<String> files = new TreeSet()
        dir.eachFile() { File item ->
            String name = item.name
            
            if( !name.startsWith( prefix ) || name.endsWith( '.bak' ) ) {
                return
            }
            
            name = name.substring( prefix.size() )
            
            if( name.startsWith( '.' ) || name.startsWith( '-' ) ) {
                name = name.substring( 1 )
            }
            name = name.removeEnd( '.sha1' )
            name = name.removeEnd( '.md5' )
            name = name.removeEnd( '.jar' )
            
            files << name
        }
        
        return new ArrayList( files )
    }
    
	void save( File file ) {
		
        String path = file.absolutePath
        
        File tmp = new File( path + '.tmp' )
        File bak = new File( path + '.bak' )
        
		XMLWriter writer = new XMLWriter( new OutputStreamWriter( new FileOutputStream( tmp ), doc.encoding ?: 'utf-8' ) )
		try {
			doc.toXML( writer )
		} finally {
			writer.close()
		}
        
        if( bak.exists() ) {
            bak.usefulDelete()
        }
        
        if( file.exists() ) {
            file.usefulRename( bak )
        }

        tmp.usefulRename( file )
	}
	
	String toString() {
		return doc.toXML()
	}
	
    static final ListNode DEPENDENCIES = new ListNode( name: 'dependencies', child: 'dependency' )
    
    List<Dependency> getDependencies() {
        return list( DEPENDENCIES ).collect() {
            Dependency.wrap( it )
        }
    }
    
    Profile profile( String name ) {
        def profiles = xml.getChild( 'profiles' )
        if( ! profiles ) {
            return null
        }
        
        def profile = profiles.getChildren( 'profile' ).find {
            def id = it.getChild( 'id' )
            return id.text == name
        }
//        println "name=${name} profile=${profile}"
        
        return profile == null ? null : new Profile( xml: profile, pom: this ) 
    }
    
    Profile getOrCreateProfile( String name ) {
        def profile = profile( name )
       
        if( profile ) {
            return new Profile( xml: profile, pom: this )
        }
        
        def profiles = PomUtils.getOrCreate( xml, 'profiles' )
        return profile == null ? createNewProfile( profiles, name ) : profile
    }
    
    private Profile createNewProfile( Element profiles, String name ) {
        def xml = new Element( 'profile' )
        profiles.addNode( xml )
        
        def id = PomUtils.getOrCreate( xml, 'id' )
        id.text = name
        
        def profile = new Profile( xml: xml, pom: this )
        profile.activeByDefault( false )
        
        PomUtils.getOrCreate( xml, 'dependencies' )
        
        return profile
    }
}

class PomUtils {
    static void removeWithIndent( Element e ) {
        if( !e || !e.parentElement ) {
            return
        }
        
        Element parent = e.parentElement
        int index = parent.nodeIndexOf( e )
        while( index > 0 ) {
            index --
            
            Node previous = parent.getNode( index )
            if( ! XMLUtils.isText( previous ) ) {
                break
            }
            
            parent.removeNode( index )
        }
        e.remove()
    }
    
    static int getLevel( Element e ) {
        int level = 0
        
        while( e ) {
            e = e.getParentElement()
            level ++
        }
        
        return -- level
    }
    
    static Element getOrCreate( Element e, String name ) {
        Element child = e.getChild( name )
        
        if( !child ) {
            child = new Element( name )
            e.addNode( child )
        }
        
        return child
    }
}

class Dependency extends PomElement {
    final static TextNode GROUP_ID = Pom.GROUP_ID
    final static TextNode ARTIFACT_ID = Pom.ARTIFACT_ID
    final static TextNode VERSION = Pom.VERSION
    final static TextNode CLASSIFIER = new TextNode( name: 'classifier' )
    final static TextNode TYPE = new TextNode( name: 'type', defaultValue: 'jar' )
    final static TextNode SCOPE = new TextNode( name: 'scope', defaultValue: 'compile' )
    final static TextNode OPTIONAL = new TextNode( name: 'optional', defaultValue: 'false' )
    
    @Override
    public String toString() {
        return "Dependency( ${key()} )";
    }
    
    String key() {
        return "${value( GROUP_ID )}:${value( ARTIFACT_ID )}:${value( VERSION )}";
    }
    
    String shortKey() {
        return "${value( GROUP_ID )}:${value( ARTIFACT_ID )}";
    }
    
    static Dependency wrap( PomElement e ) {
        if( e instanceof Dependency ) {
            return e
        }
        
        return new Dependency( xml: e.xml, pom: e.pom )
    }
}

class Profile extends PomElement {
    static final ListNode DEPENDENCIES = Pom.DEPENDENCIES
    
    List<Dependency> getDependencies() {
        return list( DEPENDENCIES ).collect() {
            Dependency.wrap( it )
        }
    }
    
    void addDependency( Dependency d ) {
        d.remove()
        xml( DEPENDENCIES ).addNode( d.xml )
    }
    
    void activeByDefault( boolean value ) {
        def activation = PomUtils.getOrCreate( xml, 'activation' )
        def activeByDefault = PomUtils.getOrCreate( activation, 'activeByDefault')
        activeByDefault.text = Boolean.toString( value )
    }
    
    void cleanUp() {
        def activation = xml.getChild( 'activation' )
        if( null == activation ) {
            return
        }
        
        def activeByDefault = activation.getChild( 'activeByDefault' )
        if( null == activeByDefault || activeByDefault.text == 'true' ) {
            return
        }
        
        PomUtils.removeWithIndent( activation )
    }
    
    String getId() {
        def id = xml.getChild( 'id' )
        return id ? id.text : null
    }
    
    @Override
    public String toString() {
        return "Profile( ${id} )";
    }
}

class XmlFormatter {
    Pom pom
    private String indentStep = '  '
    
    static void format( Pom pom ) {
        new XmlFormatter( pom: pom ).format()
    }
    
    void format() {
        pom.xml.getChild( 'profiles' )?.getChildren( 'profile' ).each {
            Profile p = new Profile( xml: it, pom: pom )
            p.cleanUp()
        }
        
        format( pom.xml )
    }
    
    void format( Element e ) {
        int level = PomUtils.getLevel( e ) + 1
        String indent = '\n' + indentStep * level
        
        int N = e.nodeCount()
//        println "level=${level} N=${N} ${e.name}"
        
        // Must work backwards because indentElement() adds new nodes
        for( int i=N-1; i>=0; i-- ) {
            Node n = e.getNode( i )
            
            if( XMLUtils.isElement( n ) ) {
                indentElement( e, i, n, indent )
            }
        }
        
        N = e.nodeCount()
        if( N > 0 ) {
            indent = '\n' + indentStep * ( level - 1 )
            
            Node n = e.getNode( N - 1 )
            if( XMLUtils.isElement( n ) ) {
//                println "Indent closing element ${e.name}"
                def textNode = new Text( indent )
                e.addNode( textNode )
            } else if( XMLUtils.isText( n ) ) {
                String text = n.text
                if( !text.endsWith( indent ) ) {
                    if( n.isWhitespace() ) {
                        n.text = indent
                    } else {
                        // Do nothing; this would modify text nodes like '<profile>id</profile>'
                    }
                }
            }
        }
    }
    
    void indentElement( Element parent, int index, Element e, String indent ) {
        boolean addNode = true
        
        if( index > 0 ) {
            Node previous = parent.getNode( index - 1 )
            
            if( XMLUtils.isText( previous ) ) {
                String text = previous.text
//                println "indent ${e.name} text=${escape(text)} indent=${escape(indent)} ws=${previous.isWhitespace()}"
                if( text.endsWith( indent ) ) {
//                    println '  same'
                    addNode = false
                } else if( previous.isWhitespace() ) {
//                    println '  reuse'
                    previous.text = indent
                    addNode = false
                }
            }
        }
        
        if( addNode ) {
            def textNode = new Text( indent )
            parent.addNode( index, textNode )
        }
        
        format( e )
    }
    
    String escape( String text ) {
        StringBuilder buffer = new StringBuilder()
        for( int i=0; i<text.size(); i++ ) {
            char c = text[i]
            
            switch( c ) {
                case '\n': buffer.append( '\\n' ); break
                case '\r': buffer.append( '\\r' ); break
                case '\t': buffer.append( '\\t' ); break
                default: buffer.append( c )
            }
        }
        
        return buffer.toString()
    }
}
