/*
 * 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("XXX 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); }
