import {migrateV8 as migrate} from './v8';
import {describe, test, expect} from 'vitest';

describe('migrate v8', () => {
    test('split text-font', () => {
        const input = {
            'version': 7,
            'sources': {
                'vector': {
                    'type': 'vector', 'url': 'http://www.example.com/example.json'
                }
            },
            'layers': [
                {
                    'id': 'minimum',
                    'type': 'symbol',
                    'source': 'vector',
                    'source-layer': 'layer',
                    'layout': {
                        'text-font': 'Helvetica, Arial',
                        'text-field': '{foo}'
                    }
                }
            ]
        } as any;

        const output = {
            'version': 8,
            'sources': {
                'vector': {
                    'type': 'vector', 'url': 'http://www.example.com/example.json'
                }
            },
            'layers': [
                {
                    'id': 'minimum',
                    'type': 'symbol',
                    'source': 'vector',
                    'source-layer': 'layer',
                    'layout': {
                        'text-font': ['Helvetica', 'Arial'],
                        'text-field': '{foo}'
                    }
                }
            ]
        };

        expect(migrate(input)).toEqual(output);
    });

    test('rename symbol-min-distance', () => {
        const input = {
            'version': 7,
            'sources': {
                'vector': {
                    'type': 'vector', 'url': 'http://www.example.com/example.json'
                }
            },
            'layers': [
                {
                    'id': 'minimum',
                    'type': 'symbol',
                    'source': 'vector',
                    'source-layer': 'layer',
                    'layout': {
                        'symbol-min-distance': 2
                    }
                }
            ]
        } as any;

        const output = {
            'version': 8,
            'sources': {
                'vector': {
                    'type': 'vector', 'url': 'http://www.example.com/example.json'
                }
            },
            'layers': [
                {
                    'id': 'minimum',
                    'type': 'symbol',
                    'source': 'vector',
                    'source-layer': 'layer',
                    'layout': {
                        'symbol-spacing': 2
                    }
                }
            ]
        };

        expect(migrate(input)).toEqual(output);
    });

    test('renames urls', () => {
        const input = {
            'version': 7,
            'sources': {
                'vector': {
                    'type': 'video', 'url': ['foo'],
                    coordinates: [[1, 0], [1, 0], [1, 0], [1, 0]]
                }
            },
            'layers': []
        } as any;

        const output = {
            'version': 8,
            'sources': {
                'vector': {
                    'type': 'video', 'urls': ['foo'],
                    coordinates: [[0, 1], [0, 1], [0, 1], [0, 1]]
                }
            },
            'layers': []
        };

        expect(migrate(input)).toEqual(output);
    });

    test('not migrate interpolated functions', () => {
        const input = {
            'version': 7,
            'sources': {
                'vector': {
                    'type': 'vector',
                    'url': 'http://www.example.com/example.json'
                }
            },
            'layers': [{
                'id': 'functions',
                'type': 'symbol',
                'source': 'vector',
                'source-layer': 'layer',
                'layout': {
                    'line-width': {
                        base: 2,
                        stops: [[1, 2], [3, 6]]
                    }
                }
            }]
        } as any;

        const output = {
            'version': 8,
            'sources': {
                'vector': {
                    'type': 'vector',
                    'url': 'http://www.example.com/example.json'
                }
            },
            'layers': [{
                'id': 'functions',
                'type': 'symbol',
                'source': 'vector',
                'source-layer': 'layer',
                'layout': {
                    'line-width': {
                        base: 2,
                        stops: [[1, 2], [3, 6]]
                    }
                }
            }]
        };

        expect(migrate(input)).toEqual(output);
    });

    test('not migrate piecewise-constant functions', () => {
        const input = {
            'version': 7,
            'sources': {
                'vector': {
                    'type': 'vector',
                    'url': 'http://www.example.com/example.json'
                }
            },
            'layers': [{
                'id': 'functions',
                'type': 'symbol',
                'source': 'vector',
                'source-layer': 'layer',
                'layout': {
                    'text-transform': {
                        stops: [[1, 'uppercase'], [3, 'lowercase']],
                    }
                }
            }]
        } as any;

        const output = {
            'version': 8,
            'sources': {
                'vector': {
                    'type': 'vector',
                    'url': 'http://www.example.com/example.json'
                }
            },
            'layers': [{
                'id': 'functions',
                'type': 'symbol',
                'source': 'vector',
                'source-layer': 'layer',
                'layout': {
                    'text-transform': {
                        stops: [[1, 'uppercase'], [3, 'lowercase']],
                    }
                }
            }]
        };

        expect(migrate(input)).toEqual(output);
    });

    test('inline constants', () => {
        const input = {
            'version': 7,
            'constants': {
                '@foo': 0.5
            },
            'sources': {
                'vector': {'type': 'vector', 'url': 'http://www.example.com/example.json'}
            },
            'layers': [
                {
                    'id': 'minimum',
                    'type': 'fill',
                    'source': 'vector',
                    'source-layer': 'layer',
                    'layout': {
                        'fill-opacity': '@foo'
                    }
                }
            ]
        } as any;

        const output = {
            'version': 8,
            'sources': {
                'vector': {'type': 'vector', 'url': 'http://www.example.com/example.json'}
            },
            'layers': [
                {
                    'id': 'minimum',
                    'type': 'fill',
                    'source': 'vector',
                    'source-layer': 'layer',
                    'layout': {
                        'fill-opacity': 0.5
                    }
                }
            ]
        };

        expect(migrate(input)).toEqual(output);
    });

    test('migrate and inline fontstack constants', () => {
        const input = {
            'version': 7,
            'constants': {
                '@foo': 'Arial Unicode,Foo Bar'
            },
            'sources': {
                'vector': {'type': 'vector', 'url': 'http://www.example.com/example.json'}
            },
            'layers': [
                {
                    'id': 'minimum',
                    'type': 'symbol',
                    'source': 'vector',
                    'source-layer': 'layer',
                    'layout': {
                        'text-font': '@foo'
                    }
                }
            ]
        } as any;

        const output = {
            'version': 8,
            'sources': {
                'vector': {'type': 'vector', 'url': 'http://www.example.com/example.json'}
            },
            'layers': [
                {
                    'id': 'minimum',
                    'type': 'symbol',
                    'source': 'vector',
                    'source-layer': 'layer',
                    'layout': {
                        'text-font': ['Arial Unicode', 'Foo Bar']
                    }
                }
            ]
        };

        expect(migrate(input)).toEqual(output);
    });

    test('update fontstack function', () => {
        const input = {
            'version': 7,
            'sources': {
                'vector': {'type': 'vector', 'url': 'http://www.example.com/example.json'}
            },
            'layers': [
                {
                    'id': 'minimum',
                    'type': 'symbol',
                    'source': 'vector',
                    'source-layer': 'layer',
                    'layout': {
                        'text-font': {
                            'base': 1,
                            'stops': [
                                [
                                    0,
                                    'Open Sans Regular, Arial Unicode MS Regular'
                                ],
                                [
                                    6,
                                    'Open Sans Semibold, Arial Unicode MS Regular'
                                ]
                            ]
                        }
                    }
                }
            ]
        } as any;

        const output = {
            'version': 8,
            'sources': {
                'vector': {'type': 'vector', 'url': 'http://www.example.com/example.json'}
            },
            'layers': [
                {
                    'id': 'minimum',
                    'type': 'symbol',
                    'source': 'vector',
                    'source-layer': 'layer',
                    'layout': {
                        'text-font': {
                            'base': 1,
                            'stops': [
                                [0, ['Open Sans Regular', 'Arial Unicode MS Regular']],
                                [6, ['Open Sans Semibold', 'Arial Unicode MS Regular']]
                            ]
                        }
                    }
                }
            ]
        };

        expect(migrate(input)).toEqual(output);
    });

    test('inline and migrate fontstack constant function', () => {
        const input = {
            'version': 7,
            'constants': {
                '@function': {
                    'base': 1,
                    'stops': [
                        [
                            0,
                            'Open Sans Regular, Arial Unicode MS Regular'
                        ],
                        [
                            6,
                            'Open Sans Semibold, Arial Unicode MS Regular'
                        ]
                    ]
                }
            },
            'sources': {
                'vector': {'type': 'vector', 'url': 'http://www.example.com/example.json'}
            },
            'layers': [
                {
                    'id': 'minimum',
                    'type': 'symbol',
                    'source': 'vector',
                    'source-layer': 'layer',
                    'layout': {
                        'text-font': '@function'
                    }
                }
            ]
        } as any;

        const output = {
            'version': 8,
            'sources': {
                'vector': {'type': 'vector', 'url': 'http://www.example.com/example.json'}
            },
            'layers': [
                {
                    'id': 'minimum',
                    'type': 'symbol',
                    'source': 'vector',
                    'source-layer': 'layer',
                    'layout': {
                        'text-font': {
                            'base': 1,
                            'stops': [
                                [0, ['Open Sans Regular', 'Arial Unicode MS Regular']],
                                [6, ['Open Sans Semibold', 'Arial Unicode MS Regular']]
                            ]
                        }
                    }
                }
            ]
        };

        expect(migrate(input)).toEqual(output);
    });

    test('update fontstack function constant', () => {
        const input = {
            'version': 7,
            'constants': {
                '@font-stack-a': 'Open Sans Regular, Arial Unicode MS Regular',
                '@font-stack-b': 'Open Sans Semibold, Arial Unicode MS Regular'
            },
            'sources': {
                'vector': {'type': 'vector', 'url': 'http://www.example.com/example.json'}
            },
            'layers': [
                {
                    'id': 'minimum',
                    'type': 'symbol',
                    'source': 'vector',
                    'source-layer': 'layer',
                    'layout': {
                        'text-font': {
                            'base': 1,
                            'stops': [
                                [0, '@font-stack-a'],
                                [6, '@font-stack-b']
                            ]
                        }
                    }
                }
            ]
        } as any;

        const output = {
            'version': 8,
            'sources': {
                'vector': {'type': 'vector', 'url': 'http://www.example.com/example.json'}
            },
            'layers': [
                {
                    'id': 'minimum',
                    'type': 'symbol',
                    'source': 'vector',
                    'source-layer': 'layer',
                    'layout': {
                        'text-font': {
                            'base': 1,
                            'stops': [
                                [0, ['Open Sans Regular', 'Arial Unicode MS Regular']],
                                [6, ['Open Sans Semibold', 'Arial Unicode MS Regular']]
                            ]
                        }
                    }
                }
            ]
        };

        expect(migrate(input)).toEqual(output);
    });

});
