/*
 * 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.felix.gogo.command;

import java.io.File;
import java.io.FileFilter;
import java.io.IOException;
import java.net.URI;
import java.util.ArrayList;
import java.util.List;
import org.apache.felix.service.command.CommandSession;
import org.apache.felix.service.command.Descriptor;
import org.osgi.framework.BundleContext;
import static org.apache.felix.gogo.command.Util.CWD;

public class Files
{
    @SuppressWarnings("unused")
    private final BundleContext m_bc;

    public Files(BundleContext bc)
    {
        m_bc = bc;
    }

    @Descriptor("get current directory")
    public File cd(
        @Descriptor("automatically supplied shell session") CommandSession session)
    {
        try
        {
            return cd(session, null);
        }
        catch (IOException ex)
        {
            throw new RuntimeException("Unable to get current directory");
        }
    }

    @Descriptor("change current directory")
    public File cd(
        @Descriptor("automatically supplied shell session") CommandSession session,
        @Descriptor("target directory") String dir)
        throws IOException
    {
        File cwd = (File) session.get(CWD);
        if (cwd == null)
        {
            cwd = new File(".").getCanonicalFile();
            session.put(CWD, cwd);
        }
        if ((dir == null) || (dir.length() == 0))
        {
            return cwd;
        }

        URI curUri = cwd.toURI();
        URI newUri = curUri.resolve(dir);

        cwd = new File(newUri);
        if (!cwd.exists())
        {
            throw new IOException("Directory does not exist");
        }
        else if (!cwd.isDirectory())
        {
            throw new IOException("Target is not a directory");
        }
        session.put(CWD, cwd.getCanonicalFile());
        return cwd;
    }

    @Descriptor("get current directory contents")
    public File[] ls(
        @Descriptor("automatically supplied shell session") CommandSession session)
        throws IOException
    {
        return ls(session, null);
    }

    @Descriptor("get specified path contents")
    public File[] ls(
        @Descriptor("automatically supplied shell session") CommandSession session,
        @Descriptor("path with optionally wildcarded file name") String pattern)
        throws IOException
    {
        pattern = ((pattern == null) || (pattern.length() == 0)) ? "." : pattern;
        pattern = ((pattern.charAt(0) != File.separatorChar) && (pattern.charAt(0) != '.'))
            ? "./" + pattern : pattern;
        int idx = pattern.lastIndexOf(File.separatorChar);
        String parent = (idx < 0) ? "." : pattern.substring(0, idx + 1);
        String target = (idx < 0) ? pattern : pattern.substring(idx + 1);

        File actualParent = ((parent.charAt(0) == File.separatorChar)
            ? new File(parent) : new File(cd(session), parent)).getCanonicalFile();

        idx = target.indexOf(File.separatorChar, idx);
        boolean isWildcarded = (target.indexOf('*', idx) >= 0);
        File[] files;
        if (isWildcarded)
        {
            if (!actualParent.exists())
            {
                throw new IOException("File does not exist");
            }
            final List<String> pieces = parseSubstring(target);
            files = actualParent.listFiles(new FileFilter() {
                public boolean accept(File pathname)
                {
                    return compareSubstring(pieces, pathname.getName());
                }
            });
        }
        else
        {
            File actualTarget = new File(actualParent, target).getCanonicalFile();
            if (!actualTarget.exists())
            {
                throw new IOException("File does not exist");
            }
            if (actualTarget.isDirectory())
            {
                files = actualTarget.listFiles();
            }
            else
            {
                files = new File[] { actualTarget };
            }
        }
        return files;
    }

    public static List<String> parseSubstring(String value)
    {
        List<String> pieces = new ArrayList<>();
        StringBuilder ss = new StringBuilder();
        // int kind = SIMPLE; // assume until proven otherwise
        boolean wasStar = false; // indicates last piece was a star
        boolean leftstar = false; // track if the initial piece is a star
        boolean rightstar = false; // track if the final piece is a star

        int idx = 0;

        // We assume (sub)strings can contain leading and trailing blanks
        boolean escaped = false;
loop:   for (;;)
        {
            if (idx >= value.length())
            {
                if (wasStar)
                {
                    // insert last piece as "" to handle trailing star
                    rightstar = true;
                }
                else
                {
                    pieces.add(ss.toString());
                    // accumulate the last piece
                    // note that in the case of
                    // (cn=); this might be
                    // the string "" (!=null)
                }
                ss.setLength(0);
                break loop;
            }

            // Read the next character and account for escapes.
            char c = value.charAt(idx++);
            if (!escaped && ((c == '(') || (c == ')')))
            {
                throw new IllegalArgumentException(
                    "Illegal value: " + value);
            }
            else if (!escaped && (c == '*'))
            {
                if (wasStar)
                {
                    // encountered two successive stars;
                    // I assume this is illegal
                    throw new IllegalArgumentException("Invalid filter string: " + value);
                }
                if (ss.length() > 0)
                {
                    pieces.add(ss.toString()); // accumulate the pieces
                    // between '*' occurrences
                }
                ss.setLength(0);
                // if this is a leading star, then track it
                if (pieces.size() == 0)
                {
                    leftstar = true;
                }
                wasStar = true;
            }
            else if (!escaped && (c == '\\'))
            {
                escaped = true;
            }
            else
            {
                escaped = false;
                wasStar = false;
                ss.append(c);
            }
        }
        if (leftstar || rightstar || pieces.size() > 1)
        {
            // insert leading and/or trailing "" to anchor ends
            if (rightstar)
            {
                pieces.add("");
            }
            if (leftstar)
            {
                pieces.add(0, "");
            }
        }
        return pieces;
    }

    public static boolean compareSubstring(List<String> pieces, String s)
    {
        // Walk the pieces to match the string
        // There are implicit stars between each piece,
        // and the first and last pieces might be "" to anchor the match.
        // assert (pieces.length > 1)
        // minimal case is <string>*<string>

        boolean result = true;
        int len = pieces.size();

        int index = 0;

loop:   for (int i = 0; i < len; i++)
        {
            String piece = pieces.get(i);

            // If this is the first piece, then make sure the
            // string starts with it.
            if (i == 0)
            {
                if (!s.startsWith(piece))
                {
                    result = false;
                    break loop;
                }
            }

            // If this is the last piece, then make sure the
            // string ends with it.
            if (i == len - 1)
            {
                result = s.endsWith(piece);
                break loop;
            }

            // If this is neither the first or last piece, then
            // make sure the string contains it.
            if ((i > 0) && (i < (len - 1)))
            {
                index = s.indexOf(piece, index);
                if (index < 0)
                {
                    result = false;
                    break loop;
                }
            }

            // Move string index beyond the matching piece.
            index += piece.length();
        }

        return result;
    }
}
