/*
 * 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.graphql.schema.aggregator.impl;

import java.io.IOException;
import java.io.Reader;
import java.nio.charset.StandardCharsets;
import java.util.Collections;
import java.util.EnumMap;
import java.util.Map;
import java.util.Optional;
import java.util.Set;
import java.util.function.Supplier;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.apache.commons.codec.binary.Hex;
import org.apache.commons.codec.digest.DigestUtils;
import org.apache.commons.io.IOUtils;
import org.apache.commons.io.input.BoundedReader;
import org.jetbrains.annotations.NotNull;

/** Reader for the partials format, which parses a partial file and
 *  provides access to its sections.
 *  See the example.partial.txt and the tests for a description of
 *  the format.
  */
public class PartialReader implements Partial {
    private static final Pattern SECTION_LINE = Pattern.compile("([A-Z]+) *:(.*)");
    private static final int EOL = '\n';

    private final Map<SectionName, Section> sections = new EnumMap<>(SectionName.class);
    private final PartialInfo partialInfo;
    private final Set<PartialInfo> requiredPartialNames;
    private final String digest;

    /** The PARTIAL section is the only required one */
    public static final String PARTIAL_SECTION = "PARTIAL";

    static class SyntaxException extends IOException {
        SyntaxException(String reason) {
            super(reason);
        }
    }

    static class ParsedSection implements Partial.Section {
        private final Supplier<Reader> sectionSource;
        private final SectionName name;
        private final String description;
        private final int startCharIndex;
        private final int endCharIndex;

        ParsedSection(Supplier<Reader> sectionSource, SectionName name, String description, int start, int end) {
            this.sectionSource = sectionSource;
            this.name = name;
            this.description = description;
            this.startCharIndex = start;
            this.endCharIndex = end;
        }

        @Override
        public SectionName getName() {
            return name;
        }

        @Override
        public String getDescription() {
            return description;
        }

        @Override
        public Reader getContent() throws IOException {
            final Reader r = sectionSource.get();
            r.skip(startCharIndex);
            return new BoundedReader(r, endCharIndex - startCharIndex);
        }
    }
    
    public PartialReader(@NotNull PartialInfo partialInfo, @NotNull Supplier<Reader> source) throws IOException {
        this.partialInfo = partialInfo;
        parse(source);
        this.digest = "SHA-256: " + Hex.encodeHexString(
                DigestUtils.updateDigest(DigestUtils.getSha256Digest(), IOUtils.toByteArray(source.get(), StandardCharsets.UTF_8)).digest());
        final Partial.Section requirements = sections.get(SectionName.REQUIRES);
        if(requirements == null) {
            requiredPartialNames = Collections.emptySet();
        } else {
            requiredPartialNames = PartialInfo.fromRequiresSection(requirements.getDescription());
        }
    }

    /* Detect lines that start with a <SECTION>: name
     *  in the input, and save them as sections
     */
    private void parse(Supplier<Reader> source) throws IOException {
        final Reader input = source.get();
        StringBuilder line = new StringBuilder();
        int c;
        int charCount = 0;
        int lastSectionStart = 0;
        String sectionName = null;
        String sectionDescription = "";
        while((c = input.read()) != -1) {
            if(c == EOL) {
                final Matcher m = SECTION_LINE.matcher(line);
                if(m.matches()) {
                    // Add previous section
                    addSectionIfNameIsSet(source, toSectionName(sectionName), sectionDescription, lastSectionStart, charCount - line.length());
                    // And setup for the new section
                    sectionName = m.group(1).trim();
                    sectionDescription = m.group(2).trim();
                    lastSectionStart = charCount + 1;
                }
                line = new StringBuilder();
            } else {
                line.append((char)c);
            }
            charCount++;
        }

        // Add last section
        addSectionIfNameIsSet(source, toSectionName(sectionName), sectionDescription, lastSectionStart, Integer.MAX_VALUE);

        // And validate
        if(!sections.containsKey(SectionName.PARTIAL)) {
            throw new SyntaxException(String.format("Missing required %s section", PARTIAL_SECTION));
        }
        
    }

    private void addSectionIfNameIsSet(Supplier<Reader> sectionSource, SectionName name, String description, int start, int end) throws SyntaxException {
        if(name == null) {
            return;
        }
        if(sections.containsKey(name)) {
            throw new SyntaxException(String.format("Duplicate section '%s'", name));
        }
        sections.put(name, new ParsedSection(sectionSource, name, description, start, end));
    }

    private SectionName toSectionName(String str) throws SyntaxException {
        if(str == null) {
            return null;
        }
        try {
            return SectionName.valueOf(str);
        } catch(Exception e) {
            throw new SyntaxException(String.format("Invalid section name '%s'", str));
        }
    }

    @Override
    public @NotNull PartialInfo getPartialInfo() {
        return partialInfo;
    }

    @Override
    public @NotNull Optional<Section> getSection(Partial.SectionName name) {
        final Section s = sections.get(name);
        return Optional.ofNullable(s);
    }

    @Override
    public @NotNull Set<PartialInfo> getRequiredPartialNames() {
        return Collections.unmodifiableSet(requiredPartialNames);
    }

    @Override
    public @NotNull String getDigest() {
        return digest;
    }
}
