/*
 * 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.
 */
import template from "./workflow-steps.template.html";
import angular from "angular";

const MODULE_NAME = 'inspector.workflow-steps';

angular.module(MODULE_NAME, [])
    .directive('workflowSteps', workflowStepsDirective);

export default MODULE_NAME;

export function workflowStepsDirective() {
    return {
        template: template,
        restrict: 'E',
        scope: {
            workflow: '=',
            task: '=?',
            nested: '=?',
        },
        controller: ['$sce', '$timeout', '$scope', '$element', controller],
        controllerAs: 'vm',
    };

    function controller($sce, $timeout, $scope, $element) {
        let vm = this;

        vm.stringify = stringify;
        $scope.workflowId = $scope.workflow.data.workflowId;

        vm.getWorkflowStepsClasses = () => {
            const c = [];
            c.push('workflow-status-'+$scope.workflow.data.status);
            if ($scope.workflow.data.status && $scope.workflow.data.status.startsWith('ERROR')) {
                c.push('workflow-error');
            }
            return c;
        }

        $scope.expandStates = {};
        if ($scope.workflow.tag && !_.isNil($scope.workflow.tag.stepIndex)) {
            $scope.expandStates[$scope.workflow.tag.stepIndex] = true;
        }

        vm.onSizeChange = () => $timeout(()=>recompute($scope, $element));

        $scope.$watch('workflow', vm.onSizeChange);
        $scope.$watch(() => $element[0].offsetHeight, (newVal, oldVal) => {
            if (oldVal!=newVal) vm.onSizeChange();
        });
        vm.onSizeChange();
    }

    function recompute($scope, $element) {
        let svg = $element[0].querySelector('#workflow-step-arrows.workflow-'+$scope.workflowId);
        let steps = $element[0].querySelectorAll('.workflow-'+$scope.workflowId+'.workflow-step');
        let arrows = makeArrows($scope.workflow, steps, { width: $scope.nested ? 32 : 56 });

        svg.innerHTML = arrows.join('\n');
    }
}

function makeArrows(workflow, steps, options) {
    const sectionWidth = ((options || {}).width) || 56;
    workflow = workflow || {};
    workflow.data = workflow.data || {};

    let [stepsPrev,stepsNext] = getWorkflowStepsPrevNext(workflow);

    const arrows = [];
    const strokeWidth = 1.5;
    const arrowheadLength = 6;
    const arrowheadWidth = arrowheadLength/3/strokeWidth;
    const defs = [];

    defs.push('<marker id="arrowhead" markerWidth="'+3*arrowheadWidth+'" markerHeight="'+3*arrowheadWidth+'" refX="'+0+'" refY="'+1.5*arrowheadWidth+'" orient="auto"><polygon fill="#000" points="0 0, '+3*arrowheadWidth+' '+1.5*arrowheadWidth+', 0 '+(3*arrowheadWidth)+'" /></marker><');
    defs.push('<marker id="arrowhead-gray" markerWidth="'+3*arrowheadWidth+'" markerHeight="'+3*arrowheadWidth+'" refX="'+0+'" refY="'+1.5*arrowheadWidth+'" orient="auto"><polygon class="fill-future" points="0 0, '+3*arrowheadWidth+' '+1.5*arrowheadWidth+', 0 '+(3*arrowheadWidth)+'" /></marker><');
    defs.push('<marker id="arrowhead-red" markerWidth="'+3*arrowheadWidth+'" markerHeight="'+3*arrowheadWidth+'" refX="'+0+'" refY="'+1.5*arrowheadWidth+'" orient="auto"><polygon class="fill-failed" points="0 0, '+3*arrowheadWidth+' '+1.5*arrowheadWidth+', 0 '+(3*arrowheadWidth)+'" /></marker><');

    if (steps) {
        let gradientCount = 0;
        function arrowSvg(y1, y2, opts) {
            var start = y1==='start/end';
            var end = y2==='start/end';

            if (y1==null || y2==null || (start&&end)) {
                // ignore if out of bounds
                return "";
            }

            if (!opts) opts = {};
            const color = opts.class ? '' : opts.color || (opts.colorEnd && opts.colorEnd==opts.colorStart ? opts.colorEnd : '#000');

            const rightFarEdge = sectionWidth;
            const rightArrowheadStart = rightFarEdge - arrowheadLength;
            const leftFarEdge = 10;
            const leftActive = rightArrowheadStart + (leftFarEdge - rightArrowheadStart) * (opts.width || 1);

            const curveX = opts.curveX || 1;
            const curveY = opts.curveY || 1;

            // const controlPointRightFarEdge = rightFarEdge + (leftActive - rightFarEdge) * curveX;
            const controlPointRightArrowheadStart = rightArrowheadStart + (leftActive - rightArrowheadStart) * curveX;
            // average of above two, to see which works best
            // const controlPointRightIntermediate = (rightFarEdge+rightArrowheadStart)/2 + (leftActive - (rightFarEdge+rightArrowheadStart)/2) * curveX;
            // const controlPointRightExaggerated = rightArrowheadStart + (leftActive - rightFarEdge) * curveX;
            const controlPointStart = controlPointRightArrowheadStart;
            const controlPointEnd = controlPointRightArrowheadStart;

            const strokeConstant = color ? 'stroke="'+color+'"' : ''

            let standard =
                'stroke-width="'+(opts.lineWidth || strokeWidth)+'" '+
                'fill="transparent" '+
                '/>';
            if (opts.class) standard = 'class="'+opts.class+'" '+standard;
            if (!opts.hideArrowhead) standard = 'marker-end="url(#'+(opts.arrowheadId || 'arrowhead')+')" ' +standard;
            if (opts.dashLength) standard = 'stroke-dasharray="'+opts.dashLength+'" '+standard;

            if (start) {
                return '<path d="M ' + leftFarEdge + ' ' + y2 +
                    ' L ' + rightArrowheadStart + ' ' + y2 + '" '+
                    strokeConstant+' '+standard;
            }
            if (end) {
                return '<path d="M ' + rightFarEdge + ' ' + y1 +
                    ' L ' + (leftFarEdge+arrowheadLength) + ' ' + y1 + '" '+
                    strokeConstant+' '+standard;
            }

            const yMCH = ((y2 - y1) / 2) * curveY;
            const yM = (y1 + y2) / 2;

            if (!opts.colorEnd || opts.colorEnd==opts.colorStart || y2==y1) {
                standard = strokeConstant + ' ' + standard;
            } else {
                const gradientId = 'gradient'+(gradientCount++);
                const gradY = y2>=y1 ? 'y2="1"' : 'y1="1"';
                defs.push('<linearGradient id="'+gradientId+'" x2="0" '+gradY+'><stop offset="0" stop-color="'+opts.colorStart+'"/><stop offset="1" stop-color="'+opts.colorEnd+'"/></linearGradient>');
                standard = 'stroke="url(#'+gradientId+')" ' + standard;
            }

            const result = '<path d="M ' + rightFarEdge + ' ' + y1 +
                // ' L ' + r0 + ' ' + y1 + ' ' +
                ' C ' + controlPointStart + ' ' + y1 + ', ' + leftActive + ' ' + (yM - yMCH) + ', ' + leftActive + ' ' + yM + ' ' +
                ' S ' + controlPointEnd + ' ' + y2 + ', ' + rightArrowheadStart + ' ' + y2 + '" '+standard;
            return result;
        }

        function stepY(n) {
            if (n==-1) return 'start/end';
            if (!steps || n<0 || n>=steps.length || _.isNil(n)) {
                console.log("workflow arrow bounds error", steps, n);
                return null;
            }
            return steps[n].offsetTop + steps[n].offsetHeight / 2;
        }

        function arrowStep(n1, n2, opts) {
            let s1 = stepY(n1);
            let s2 = stepY(n2);

            const deltaForArrowMax = 6;
            const deltaForArrowTarget = 0.125;
            if (typeof s1 === "number") s1 += Math.min(steps[n1].offsetHeight * deltaForArrowTarget, deltaForArrowMax);
            if (typeof s2 === "number") s2 -= Math.min(steps[n2].offsetHeight * deltaForArrowTarget, deltaForArrowMax);
            return arrowSvg(s1, s2, opts);
        }

        let jumpSizes = {1: true};

        function arrowStep2(prev, i, opts) {
            let curveX = 0.5;
            let curveY = 0.75;
            let width = 0.5;
            if (prev==-1 || i==-1) {
                // curve values don't matter for start/end
            } else if (prev==i) {
                width = 0.15;
                curveX = 0.1;
                curveY = 0.75;
            } else {
                let rank = jumpSizes.indexOf(''+Math.abs(prev-i));
                if (rank<0) {
                    console.log("Missing workflow link: ", prev, i);
                    rank = 0;
                }
                if (prev > i) rank = rank + 0.5;
                width = 0.2 + 0.6 * (rank + 0.5) / (jumpSizes.length + 0.5);
                curveX = 0.8 + 0.2*width;
                curveY = 0.8 + 0.2*width;
                // higher values (above) look nicer, but make disambiguation of complex paths harder
                // curveX = 0.5 + 0.3*width;
                // curveY = 0.4 + 0.4*width;
            }
            return arrowStep(prev, i, {hideArrowhead: prev==i, width, curveX, curveY, ...opts});
        }

        function colorFor(step, references) {
            if (!references) return 'red';
            const i = references.indexOf(step);
            if (i==-3) return 'red';
            // skew quadratically for lightness
            const skewTowards1 = x => (1 - (1-x)*(1-x));
            let gray = Math.round(240 * skewTowards1(i / references.length) );
            return 'rgb('+gray+','+gray+','+gray+')';
        }

        let arrowSpecs = {};
        function recordTransition(from, to, opts) {
            if (to!=-1 && from!=-1 && to!=from) {
                jumpSizes[Math.abs(from-to)] = true;
            }
            if (to<0) to=-1; // in record, -2 means end, -3 means error; here -1 means end because nothing should go to -1
            if (arrowSpecs[[from,to]]) {
                // prefer earlier additions (real steps) over theoretical ones
            } else {
                arrowSpecs[[from, to]] = {from, to, ...(opts || {})};
            }
        }

        for (var i = -3; i < steps.length; i++) {
            const prevsHere = stepsPrev[i];
            if (prevsHere && prevsHere.length) {
                prevsHere.forEach(prev => {
                    // last in list has higher z-order; this ensures within each prevStep we preserve order,
                    // so inbound arrows are correct. currently we also prefer earlier steps, which isn't quite right for outbound arrows;
                    // ideally we'd reconstruct the flow order, but that's a bit more work than we want to do just now.
                    // so insertion point is always 0. (header items added at end so we don't need to include those here.)
                    recordTransition(prev, i, { insertionPoint: 0, visited: true, colorStart: colorFor(i, stepsNext[prev]), colorEnd: colorFor(prev, prevsHere) });
                });
            }
        }

        // now make pale arrows for the default flow
        var indexOfId = {};
        for (var i = 0; i < steps.length; i++) {
            const s = workflow.data.stepsDefinition[i];
            if (!s) console.log("Missing step", i, workflow.data, steps);
            if (s.id) indexOfId[s.id] = i;
        }

        function isStepType(step, type) {
            if (!step) return false;
            if (step.type) return step.type == type;
            let s = step.startsWith ? step : step.s || step.shorthand || step.userSuppliedShorthand;
            if (s) return s == type || s.startsWith(type);
            return false;
        }

        for (var i = 0; i < steps.length; i++) {
            const s = workflow.data.stepsDefinition[i];

            let opts = { insertionPoint: 0 };

            // errors shown elsewhere
            // if (workflow.data.currentStepIndex === i && workflow.data.status && workflow.data.status.startsWith('ERROR')) {
            //     recordTransition(i, -2, { ...opts, class: 'arrow-failed', arrowheadId: 'arrowhead-red' });
            // }

            opts = { ...opts, class: 'arrow-future', arrowheadId: 'arrowhead-gray', dashLength: 8 };

            let next = null;
            if (s.next) {
                if (s.next.toLowerCase()=='end') next = -1;
                else if (indexOfId[s.next]) next = indexOfId[s.next];
            }
            if (isStepType(s, 'return')) next = -1;

            if (next!=null) {
                // special next per step
                recordTransition(i, next, opts);
                if (!s.condition) continue;
            }
            // if nothing special, or if was conditional, then go to next step
            // (only go forward 1, even if it is conditional, otherwise too many arrows)

            next = i+1;
            if (i + 1 >= steps.length) next = -1;
            recordTransition(i, next, opts);
        }

        jumpSizes = Object.keys(jumpSizes).sort();

        // insert arrows
        Object.values(arrowSpecs).forEach(arrowSpec =>
            arrows.splice(arrowSpec.insertionPoint || 0, 0, arrowStep2(arrowSpec.from, arrowSpec.to, arrowSpec)) );
        // then defs at start
        arrows.splice(0, 0, '<defs>'+defs.join('')+'</defs>');
    }
    return arrows;
}

function getWorkflowStepsPrevNext(workflow) {
    let stepsPrev = {}
    let stepsNext = {}

    if (workflow && workflow.data.oldStepInfo) {
        Object.entries(workflow.data.oldStepInfo).forEach(([k,v]) => {
            stepsPrev[k] = v.previous || [];
            stepsNext[k] = v.next || [];
        });
    }

    // mock data
    // // first in list is most recent
    // stepsPrev = {
    //     '-1': [ 3 ],
    //     0: [ -1 ],
    //     1: [ 0 ],
    //     2: [ 1 ],
    //     3: [ 2 ],
    // }
    // stepsNext = {
    //     '-1': [ 0 ],
    //     0: [ 1 ],
    //     1: [ 2 ],
    //     2: [ 3 ],
    //     3: [ -1 ],
    // }
    //
    // stepsPrev = {
    //     '-1': [ 2 ],
    //     0: [ -1 ],
    //     1: [ 1, 4, 0 ],
    //     2: [ 3, 1 ],
    //     3: [ 2 ],
    //     4: [ 1 ],
    // }
    // stepsNext = {
    //     '-1': [ 0 ],
    //     0: [ 1 ],
    //     1: [ 2, 1, 4, 0 ],
    //     2: [ -1, 3 ],
    //     3: [ 2 ],
    //     4: [ 1 ],
    // }

    // // even more complex
    // stepsPrev = {
    //     '-1': [ 2 ],
    //     0: [ 3, -1 ],
    //     1: [ 1, 4, 0 ],
    //     2: [ 3, 1 ],
    //     3: [ 2, 0 ],
    //     4: [ 1 ],
    // }
    // stepsNext = {
    //     '-1': [ 0 ],
    //     0: [ 1, 3 ],
    //     1: [ 2, 1, 4, 0 ],
    //     2: [ -1, 3 ],
    //     3: [ 2, 0 ],
    //     4: [ 1 ],
    // }

    return [stepsPrev, stepsNext];
}

function stringify(data) { return JSON.stringify(data, null, 2); }
