/*
 * 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.logging.log4j.core.appender.rolling;

import java.io.File;
import java.io.IOException;
import java.nio.file.DirectoryStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.ArrayList;
import java.util.List;
import java.util.SortedMap;
import java.util.TreeMap;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.apache.logging.log4j.Logger;
import org.apache.logging.log4j.LoggingException;
import org.apache.logging.log4j.core.appender.rolling.action.Action;
import org.apache.logging.log4j.core.appender.rolling.action.CompositeAction;
import org.apache.logging.log4j.core.lookup.StrSubstitutor;
import org.apache.logging.log4j.core.pattern.NotANumber;
import org.apache.logging.log4j.status.StatusLogger;

/**
 *
 */
public abstract class AbstractRolloverStrategy implements RolloverStrategy {

    /**
     * Allow subclasses access to the status logger without creating another instance.
     */
    protected static final Logger LOGGER = StatusLogger.getLogger();

    public static final Pattern PATTERN_COUNTER= Pattern.compile(".*%((?<ZEROPAD>0)?(?<PADDING>\\d+))?i.*");

    protected final StrSubstitutor strSubstitutor;

    protected AbstractRolloverStrategy(final StrSubstitutor strSubstitutor) {
        this.strSubstitutor = strSubstitutor;
    }


    public StrSubstitutor getStrSubstitutor() {
        return strSubstitutor;
    }

    protected Action merge(final Action compressAction, final List<Action> custom, final boolean stopOnError) {
        if (custom.isEmpty()) {
            return compressAction;
        }
        if (compressAction == null) {
            return new CompositeAction(custom, stopOnError);
        }
        final List<Action> all = new ArrayList<>();
        all.add(compressAction);
        all.addAll(custom);
        return new CompositeAction(all, stopOnError);
    }

    protected int suffixLength(final String lowFilename) {
        for (final FileExtension extension : FileExtension.values()) {
            if (extension.isExtensionFor(lowFilename)) {
                return extension.length();
            }
        }
        return 0;
    }


    protected SortedMap<Integer, Path> getEligibleFiles(final RollingFileManager manager) {
        return getEligibleFiles(manager, true);
    }

    protected SortedMap<Integer, Path> getEligibleFiles(final RollingFileManager manager,
                                                        final boolean isAscending) {
        final StringBuilder buf = new StringBuilder();
        final String pattern = manager.getPatternProcessor().getPattern();
        manager.getPatternProcessor().formatFileName(strSubstitutor, buf, NotANumber.NAN);
        final String fileName = manager.isDirectWrite() ? "" : manager.getFileName();
        return getEligibleFiles(fileName, buf.toString(), pattern, isAscending);
    }

    protected SortedMap<Integer, Path> getEligibleFiles(final String path, final String pattern) {
        return getEligibleFiles("", path, pattern, true);
    }

    protected SortedMap<Integer, Path> getEligibleFiles(final String currentFile, final String path,
            final String logfilePattern, final boolean isAscending) {
        final TreeMap<Integer, Path> eligibleFiles = new TreeMap<>();
        final File file = new File(path);
        File parent = file.getParentFile();
        if (parent == null) {
            parent = new File(".");
        } else {
            parent.mkdirs();
        }
        if (!PATTERN_COUNTER.matcher(logfilePattern).matches()) {
            return eligibleFiles;
        }
        final Path dir = parent.toPath();
        String fileName = file.getName();
        final int suffixLength = suffixLength(fileName);
        if (suffixLength > 0) {
            fileName = fileName.substring(0, fileName.length() - suffixLength) + ".*";
        }
        final String filePattern = fileName.replaceFirst("0?\\u0000", "(0?\\\\d+)");
        final Pattern pattern = Pattern.compile(filePattern);
        final Path current = currentFile.length() > 0 ? new File(currentFile).toPath() : null;
        LOGGER.debug("Current file: {}", currentFile);

        try (DirectoryStream<Path> stream = Files.newDirectoryStream(dir)) {
            for (final Path entry: stream) {
                final Matcher matcher = pattern.matcher(entry.toFile().getName());
                if (matcher.matches() && !entry.equals(current)) {
                    try {
                        final Integer index = Integer.parseInt(matcher.group(1));
                        eligibleFiles.put(index, entry);
                    } catch (NumberFormatException ex) {
                        LOGGER.debug("Ignoring file {} which matches pattern but the index is invalid.",
                                entry.toFile().getName());
                    }
                }
            }
        } catch (final IOException ioe) {
            throw new LoggingException("Error reading folder " + dir + " " + ioe.getMessage(), ioe);
        }
        return isAscending? eligibleFiles : eligibleFiles.descendingMap();
    }
}
