/*
 * 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.nlpcraft.examples.alarm;

import org.apache.nlpcraft.model.*;
import java.time.*;
import java.time.format.*;
import java.util.*;

import static java.time.temporal.ChronoUnit.*;

/**
 * Alarm example data model.
 * <p>
 * This example provides a simple "alarm clock" interface where you can ask to set the timer
 * for a specific duration from now expressed in hours, minutes and/or seconds. You can say "ping me in 3 minutes",
 * "buzz me in an hour and 15 minutes", or "set my alarm for 30 secs". When the timers is up it will
 * simply print out "BEEP BEEP BEEP" in the probe console.
 * <p>
 * See 'README.md' file in the same folder for running and testing instructions.
 */
public class AlarmModel extends NCModelFileAdapter {
    private static final DateTimeFormatter FMT =
        DateTimeFormatter.ofPattern("HH'h' mm'm' ss's'").withZone(ZoneId.systemDefault());
    
    private final Timer timer = new Timer();
    
    public AlarmModel() {
        // Loading the model from the file in the classpath.
        super("org/apache/nlpcraft/examples/alarm/alarm_model.json");
    }

    /**
     * Callback on intent match.
     *
     * @param ctx Intent solver context.
     * @return Query result.
     */
    @NCIntentRef("alarm")
    @NCIntentSample({
        "Ping me in 3 minutes",
        "Buzz me in an hour and 15mins",
        "Set my alarm for 30s"
    })
    private NCResult onMatch(
        NCIntentMatch ctx,
        @NCIntentTerm("nums") List<NCToken> numToks
    ) {
        if (ctx.isAmbiguous())
            throw new NCRejection("Not exact match.");

        long unitsCnt = numToks.stream().map(tok -> (String)tok.meta("num:unit")).distinct().count();
        
        if (unitsCnt != numToks.size())
            throw new NCRejection("Ambiguous time units.");
    
        LocalDateTime now = LocalDateTime.now();
        LocalDateTime dt = now;
    
        for (NCToken num : numToks) {
            String unit = num.meta("nlpcraft:num:unit");
    
            // Skip possible fractional to simplify.
            long v = ((Double)num.meta("nlpcraft:num:from")).longValue();
            
            if (v <= 0)
                throw new NCRejection("Value must be positive: " + unit);
    
            switch (unit) {
                case "second": { dt = dt.plusSeconds(v); break; }
                case "minute": { dt = dt.plusMinutes(v); break; }
                case "hour": { dt = dt.plusHours(v); break; }
                case "day": { dt = dt.plusDays(v); break; }
                case "week": { dt = dt.plusWeeks(v); break; }
                case "month": { dt = dt.plusMonths(v); break; }
                case "year": { dt = dt.plusYears(v); break; }
        
                default:
                    // It shouldn't be assert, because 'datetime' unit can be extended.
                    throw new NCRejection("Unsupported time unit: " + unit);
            }
        }
    
        long ms = now.until(dt, MILLIS);
        
        assert ms >= 0;
    
        timer.schedule(
            new TimerTask() {
                @Override
                public void run() {
                    System.out.println(
                        "BEEP BEEP BEEP for: " + ctx.getContext().getRequest().getNormalizedText() + ""
                    );
                }
            },
            ms
        );
    
        return NCResult.text("Timer set for: " + FMT.format(dt));
    }

    @Override
    public void onDiscard() {
        // Clean up when model gets discarded (e.g. during testing).
        timer.cancel();
    }
}
