/*
 * Copyright 2016 Google Inc.
 *
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */

#include "modules/svg/include/SkSVGDOM.h"

#include "include/core/SkData.h"
#include "include/core/SkFontMgr.h"
#include "include/core/SkString.h"
#include "include/private/SkAssert.h"
#include "include/private/SkTo.h"
#include "modules/skshaper/include/SkShaper_factory.h"
#include "modules/svg/include/SkSVGAttribute.h"
#include "modules/svg/include/SkSVGAttributeParser.h"
#include "modules/svg/include/SkSVGCircle.h"
#include "modules/svg/include/SkSVGClipPath.h"
#include "modules/svg/include/SkSVGDefs.h"
#include "modules/svg/include/SkSVGEllipse.h"
#include "modules/svg/include/SkSVGFeBlend.h"
#include "modules/svg/include/SkSVGFeColorMatrix.h"
#include "modules/svg/include/SkSVGFeComponentTransfer.h"
#include "modules/svg/include/SkSVGFeComposite.h"
#include "modules/svg/include/SkSVGFeDisplacementMap.h"
#include "modules/svg/include/SkSVGFeFlood.h"
#include "modules/svg/include/SkSVGFeGaussianBlur.h"
#include "modules/svg/include/SkSVGFeImage.h"
#include "modules/svg/include/SkSVGFeLightSource.h"
#include "modules/svg/include/SkSVGFeLighting.h"
#include "modules/svg/include/SkSVGFeMerge.h"
#include "modules/svg/include/SkSVGFeMorphology.h"
#include "modules/svg/include/SkSVGFeOffset.h"
#include "modules/svg/include/SkSVGFeTurbulence.h"
#include "modules/svg/include/SkSVGFilter.h"
#include "modules/svg/include/SkSVGG.h"
#include "modules/svg/include/SkSVGImage.h"
#include "modules/svg/include/SkSVGLine.h"
#include "modules/svg/include/SkSVGLinearGradient.h"
#include "modules/svg/include/SkSVGMask.h"
#include "modules/svg/include/SkSVGNode.h"
#include "modules/svg/include/SkSVGPath.h"
#include "modules/svg/include/SkSVGPattern.h"
#include "modules/svg/include/SkSVGPoly.h"
#include "modules/svg/include/SkSVGRadialGradient.h"
#include "modules/svg/include/SkSVGRect.h"
#include "modules/svg/include/SkSVGRenderContext.h"
#include "modules/svg/include/SkSVGSVG.h"
#include "modules/svg/include/SkSVGStop.h"
#include "modules/svg/include/SkSVGText.h"
#include "modules/svg/include/SkSVGTypes.h"
#include "modules/svg/include/SkSVGUse.h"
#include "modules/svg/include/SkSVGValue.h"
#include "src/core/SkTSearch.h"
#include "src/core/SkTraceEvent.h"
#include "src/xml/SkDOM.h"

#include <array>
#include <cstring>
#include <stdint.h>
#include <tuple>
#include <utility>

namespace {

bool SetIRIAttribute(const sk_sp<SkSVGNode>& node, SkSVGAttribute attr,
                      const char* stringValue) {
    auto parseResult = SkSVGAttributeParser::parse<SkSVGIRI>(stringValue);
    if (!parseResult.has_value()) {
        return false;
    }

    node->setAttribute(attr, SkSVGStringValue(parseResult->iri()));
    return true;
}

bool SetStringAttribute(const sk_sp<SkSVGNode>& node, SkSVGAttribute attr,
                           const char* stringValue) {
    SkString str(stringValue, strlen(stringValue));
    SkSVGStringType strType = SkSVGStringType(str);
    node->setAttribute(attr, SkSVGStringValue(strType));
    return true;
}

bool SetTransformAttribute(const sk_sp<SkSVGNode>& node, SkSVGAttribute attr,
                           const char* stringValue) {
    auto parseResult = SkSVGAttributeParser::parse<SkSVGTransformType>(stringValue);
    if (!parseResult.has_value()) {
        return false;
    }

    node->setAttribute(attr, SkSVGTransformValue(*parseResult));
    return true;
}

bool SetLengthAttribute(const sk_sp<SkSVGNode>& node, SkSVGAttribute attr,
                        const char* stringValue) {
    auto parseResult = SkSVGAttributeParser::parse<SkSVGLength>(stringValue);
    if (!parseResult.has_value()) {
        return false;
    }

    node->setAttribute(attr, SkSVGLengthValue(*parseResult));
    return true;
}

bool SetViewBoxAttribute(const sk_sp<SkSVGNode>& node, SkSVGAttribute attr,
                         const char* stringValue) {
    SkSVGViewBoxType viewBox;
    SkSVGAttributeParser parser(stringValue);
    if (!parser.parseViewBox(&viewBox)) {
        return false;
    }

    node->setAttribute(attr, SkSVGViewBoxValue(viewBox));
    return true;
}

bool SetObjectBoundingBoxUnitsAttribute(const sk_sp<SkSVGNode>& node,
                                        SkSVGAttribute attr,
                                        const char* stringValue) {
    auto parseResult = SkSVGAttributeParser::parse<SkSVGObjectBoundingBoxUnits>(stringValue);
    if (!parseResult.has_value()) {
        return false;
    }

    node->setAttribute(attr, SkSVGObjectBoundingBoxUnitsValue(*parseResult));
    return true;
}

bool SetPreserveAspectRatioAttribute(const sk_sp<SkSVGNode>& node, SkSVGAttribute attr,
                                     const char* stringValue) {
    SkSVGPreserveAspectRatio par;
    SkSVGAttributeParser parser(stringValue);
    if (!parser.parsePreserveAspectRatio(&par)) {
        return false;
    }

    node->setAttribute(attr, SkSVGPreserveAspectRatioValue(par));
    return true;
}

SkString TrimmedString(const char* first, const char* last) {
    SkASSERT(first);
    SkASSERT(last);
    SkASSERT(first <= last);

    while (first <= last && *first <= ' ') { first++; }
    while (first <= last && *last  <= ' ') { last--; }

    SkASSERT(last - first + 1 >= 0);
    return SkString(first, SkTo<size_t>(last - first + 1));
}

// Breaks a "foo: bar; baz: ..." string into key:value pairs.
class StyleIterator {
public:
    StyleIterator(const char* str) : fPos(str) { }

    std::tuple<SkString, SkString> next() {
        SkString name, value;

        if (fPos) {
            const char* sep = this->nextSeparator();
            SkASSERT(*sep == ';' || *sep == '\0');

            const char* valueSep = strchr(fPos, ':');
            if (valueSep && valueSep < sep) {
                name  = TrimmedString(fPos, valueSep - 1);
                value = TrimmedString(valueSep + 1, sep - 1);
            }

            fPos = *sep ? sep + 1 : nullptr;
        }

        return std::make_tuple(name, value);
    }

private:
    const char* nextSeparator() const {
        const char* sep = fPos;
        while (*sep != ';' && *sep != '\0') {
            sep++;
        }
        return sep;
    }

    const char* fPos;
};

bool set_string_attribute(const sk_sp<SkSVGNode>& node, const char* name, const char* value);

bool SetStyleAttributes(const sk_sp<SkSVGNode>& node, SkSVGAttribute,
                        const char* stringValue) {

    SkString name, value;
    StyleIterator iter(stringValue);
    for (;;) {
        std::tie(name, value) = iter.next();
        if (name.isEmpty()) {
            break;
        }
        set_string_attribute(node, name.c_str(), value.c_str());
    }

    return true;
}

template<typename T>
struct SortedDictionaryEntry {
    const char* fKey;
    const T     fValue;
};

struct AttrParseInfo {
    SkSVGAttribute fAttr;
    bool (*fSetter)(const sk_sp<SkSVGNode>& node, SkSVGAttribute attr, const char* stringValue);
};

static constexpr auto gAttributeParseInfo = std::to_array<SortedDictionaryEntry<AttrParseInfo>>({
    { "cx"                 , { SkSVGAttribute::kCx               , SetLengthAttribute       }},
    { "cy"                 , { SkSVGAttribute::kCy               , SetLengthAttribute       }},
    { "filterUnits"        , { SkSVGAttribute::kFilterUnits      ,
                               SetObjectBoundingBoxUnitsAttribute }},
    // focal point x & y
    { "fx"                 , { SkSVGAttribute::kFx               , SetLengthAttribute       }},
    { "fy"                 , { SkSVGAttribute::kFy               , SetLengthAttribute       }},
    { "height"             , { SkSVGAttribute::kHeight           , SetLengthAttribute       }},
    { "preserveAspectRatio", { SkSVGAttribute::kPreserveAspectRatio,
                               SetPreserveAspectRatioAttribute }},
    { "r"                  , { SkSVGAttribute::kR                , SetLengthAttribute       }},
    { "rx"                 , { SkSVGAttribute::kRx               , SetLengthAttribute       }},
    { "ry"                 , { SkSVGAttribute::kRy               , SetLengthAttribute       }},
    { "style"              , { SkSVGAttribute::kUnknown          , SetStyleAttributes       }},
    { "text"               , { SkSVGAttribute::kText             , SetStringAttribute       }},
    { "transform"          , { SkSVGAttribute::kTransform        , SetTransformAttribute    }},
    { "viewBox"            , { SkSVGAttribute::kViewBox          , SetViewBoxAttribute      }},
    { "width"              , { SkSVGAttribute::kWidth            , SetLengthAttribute       }},
    { "x"                  , { SkSVGAttribute::kX                , SetLengthAttribute       }},
    { "x1"                 , { SkSVGAttribute::kX1               , SetLengthAttribute       }},
    { "x2"                 , { SkSVGAttribute::kX2               , SetLengthAttribute       }},
    { "xlink:href"         , { SkSVGAttribute::kHref             , SetIRIAttribute          }},
    { "y"                  , { SkSVGAttribute::kY                , SetLengthAttribute       }},
    { "y1"                 , { SkSVGAttribute::kY1               , SetLengthAttribute       }},
    { "y2"                 , { SkSVGAttribute::kY2               , SetLengthAttribute       }},
});

static constexpr auto gTagFactories = std::to_array<SortedDictionaryEntry<sk_sp<SkSVGNode> (*)()>>({
    { "a"                  , []() -> sk_sp<SkSVGNode> { return SkSVGG::Make();                   }},
    { "circle"             , []() -> sk_sp<SkSVGNode> { return SkSVGCircle::Make();              }},
    { "clipPath"           , []() -> sk_sp<SkSVGNode> { return SkSVGClipPath::Make();            }},
    { "defs"               , []() -> sk_sp<SkSVGNode> { return SkSVGDefs::Make();                }},
    { "ellipse"            , []() -> sk_sp<SkSVGNode> { return SkSVGEllipse::Make();             }},
    { "feBlend"            , []() -> sk_sp<SkSVGNode> { return SkSVGFeBlend::Make();             }},
    { "feColorMatrix"      , []() -> sk_sp<SkSVGNode> { return SkSVGFeColorMatrix::Make();       }},
    { "feComponentTransfer", []() -> sk_sp<SkSVGNode> { return SkSVGFeComponentTransfer::Make(); }},
    { "feComposite"        , []() -> sk_sp<SkSVGNode> { return SkSVGFeComposite::Make();         }},
    { "feDiffuseLighting"  , []() -> sk_sp<SkSVGNode> { return SkSVGFeDiffuseLighting::Make();   }},
    { "feDisplacementMap"  , []() -> sk_sp<SkSVGNode> { return SkSVGFeDisplacementMap::Make();   }},
    { "feDistantLight"     , []() -> sk_sp<SkSVGNode> { return SkSVGFeDistantLight::Make();      }},
    { "feFlood"            , []() -> sk_sp<SkSVGNode> { return SkSVGFeFlood::Make();             }},
    { "feFuncA"            , []() -> sk_sp<SkSVGNode> { return SkSVGFeFunc::MakeFuncA();         }},
    { "feFuncB"            , []() -> sk_sp<SkSVGNode> { return SkSVGFeFunc::MakeFuncB();         }},
    { "feFuncG"            , []() -> sk_sp<SkSVGNode> { return SkSVGFeFunc::MakeFuncG();         }},
    { "feFuncR"            , []() -> sk_sp<SkSVGNode> { return SkSVGFeFunc::MakeFuncR();         }},
    { "feGaussianBlur"     , []() -> sk_sp<SkSVGNode> { return SkSVGFeGaussianBlur::Make();      }},
    { "feImage"            , []() -> sk_sp<SkSVGNode> { return SkSVGFeImage::Make();             }},
    { "feMerge"            , []() -> sk_sp<SkSVGNode> { return SkSVGFeMerge::Make();             }},
    { "feMergeNode"        , []() -> sk_sp<SkSVGNode> { return SkSVGFeMergeNode::Make();         }},
    { "feMorphology"       , []() -> sk_sp<SkSVGNode> { return SkSVGFeMorphology::Make();        }},
    { "feOffset"           , []() -> sk_sp<SkSVGNode> { return SkSVGFeOffset::Make();            }},
    { "fePointLight"       , []() -> sk_sp<SkSVGNode> { return SkSVGFePointLight::Make();        }},
    { "feSpecularLighting" , []() -> sk_sp<SkSVGNode> { return SkSVGFeSpecularLighting::Make();  }},
    { "feSpotLight"        , []() -> sk_sp<SkSVGNode> { return SkSVGFeSpotLight::Make();         }},
    { "feTurbulence"       , []() -> sk_sp<SkSVGNode> { return SkSVGFeTurbulence::Make();        }},
    { "filter"             , []() -> sk_sp<SkSVGNode> { return SkSVGFilter::Make();              }},
    { "g"                  , []() -> sk_sp<SkSVGNode> { return SkSVGG::Make();                   }},
    { "image"              , []() -> sk_sp<SkSVGNode> { return SkSVGImage::Make();               }},
    { "line"               , []() -> sk_sp<SkSVGNode> { return SkSVGLine::Make();                }},
    { "linearGradient"     , []() -> sk_sp<SkSVGNode> { return SkSVGLinearGradient::Make();      }},
    { "mask"               , []() -> sk_sp<SkSVGNode> { return SkSVGMask::Make();                }},
    { "path"               , []() -> sk_sp<SkSVGNode> { return SkSVGPath::Make();                }},
    { "pattern"            , []() -> sk_sp<SkSVGNode> { return SkSVGPattern::Make();             }},
    { "polygon"            , []() -> sk_sp<SkSVGNode> { return SkSVGPoly::MakePolygon();         }},
    { "polyline"           , []() -> sk_sp<SkSVGNode> { return SkSVGPoly::MakePolyline();        }},
    { "radialGradient"     , []() -> sk_sp<SkSVGNode> { return SkSVGRadialGradient::Make();      }},
    { "rect"               , []() -> sk_sp<SkSVGNode> { return SkSVGRect::Make();                }},
    { "stop"               , []() -> sk_sp<SkSVGNode> { return SkSVGStop::Make();                }},
//    "svg" handled explicitly
    { "text"               , []() -> sk_sp<SkSVGNode> { return SkSVGText::Make();                }},
    { "textPath"           , []() -> sk_sp<SkSVGNode> { return SkSVGTextPath::Make();            }},
    { "tspan"              , []() -> sk_sp<SkSVGNode> { return SkSVGTSpan::Make();               }},
    { "use"                , []() -> sk_sp<SkSVGNode> { return SkSVGUse::Make();                 }},
});

struct ConstructionContext {
    ConstructionContext(SkSVGIDMapper* mapper) : fParent(nullptr), fIDMapper(mapper) {}
    ConstructionContext(const ConstructionContext& other, const sk_sp<SkSVGNode>& newParent)
        : fParent(newParent.get()), fIDMapper(other.fIDMapper) {}

    SkSVGNode*     fParent;
    SkSVGIDMapper* fIDMapper;
};

bool set_string_attribute(const sk_sp<SkSVGNode>& node, const char* name, const char* value) {
    if (node->parseAndSetAttribute(name, value)) {
        // Handled by new code path
        return true;
    }

    const int attrIndex = SkStrSearch(&gAttributeParseInfo[0].fKey,
                                      SkTo<int>(std::size(gAttributeParseInfo)),
                                      name, sizeof(gAttributeParseInfo[0]));
    if (attrIndex < 0) {
#if defined(SK_VERBOSE_SVG_PARSING)
        SkDebugf("unhandled attribute: %s\n", name);
#endif
        return false;
    }

    SkASSERT(SkTo<size_t>(attrIndex) < std::size(gAttributeParseInfo));
    const auto& attrInfo = gAttributeParseInfo[attrIndex].fValue;
    if (!attrInfo.fSetter(node, attrInfo.fAttr, value)) {
#if defined(SK_VERBOSE_SVG_PARSING)
        SkDebugf("could not parse attribute: '%s=\"%s\"'\n", name, value);
#endif
        return false;
    }

    return true;
}

void parse_node_attributes(const SkDOM& xmlDom, const SkDOM::Node* xmlNode,
                           const sk_sp<SkSVGNode>& svgNode, SkSVGIDMapper* mapper) {
    const char* name, *value;
    SkDOM::AttrIter attrIter(xmlDom, xmlNode);
    while ((name = attrIter.next(&value))) {
        // We're handling id attributes out of band for now.
        if (!strcmp(name, "id")) {
            mapper->set(SkString(value), svgNode);
            continue;
        }
        set_string_attribute(svgNode, name, value);
    }
}

sk_sp<SkSVGNode> construct_svg_node(const SkDOM& dom, const ConstructionContext& ctx,
                                    const SkDOM::Node* xmlNode) {
    const char* elem = dom.getName(xmlNode);
    const SkDOM::Type elemType = dom.getType(xmlNode);

    if (elemType == SkDOM::kText_Type) {
        // Text literals require special handling.
        SkASSERT(dom.countChildren(xmlNode) == 0);
        auto txt = SkSVGTextLiteral::Make();
        txt->setText(SkString(dom.getName(xmlNode)));
        ctx.fParent->appendChild(std::move(txt));

        return nullptr;
    }

    SkASSERT(elemType == SkDOM::kElement_Type);

    auto make_node = [](const ConstructionContext& ctx, const char* elem) -> sk_sp<SkSVGNode> {
        if (strcmp(elem, "svg") == 0) {
            // Outermost SVG element must be tagged as such.
            return SkSVGSVG::Make(ctx.fParent ? SkSVGSVG::Type::kInner
                                              : SkSVGSVG::Type::kRoot);
        }

        const int tagIndex = SkStrSearch(&gTagFactories[0].fKey,
                                         SkTo<int>(std::size(gTagFactories)),
                                         elem, sizeof(gTagFactories[0]));
        if (tagIndex < 0) {
#if defined(SK_VERBOSE_SVG_PARSING)
            SkDebugf("unhandled element: <%s>\n", elem);
#endif
            return nullptr;
        }
        SkASSERT(SkTo<size_t>(tagIndex) < std::size(gTagFactories));

        return gTagFactories[tagIndex].fValue();
    };

    auto node = make_node(ctx, elem);
    if (!node) {
        return nullptr;
    }

    parse_node_attributes(dom, xmlNode, node, ctx.fIDMapper);

    ConstructionContext localCtx(ctx, node);
    for (auto* child = dom.getFirstChild(xmlNode, nullptr); child;
         child = dom.getNextSibling(child)) {
        sk_sp<SkSVGNode> childNode = construct_svg_node(dom, localCtx, child);
        if (childNode) {
            node->appendChild(std::move(childNode));
        }
    }

    return node;
}

} // anonymous namespace

SkSVGDOM::Builder& SkSVGDOM::Builder::setFontManager(sk_sp<SkFontMgr> fmgr) {
    fFontMgr = std::move(fmgr);
    return *this;
}

SkSVGDOM::Builder& SkSVGDOM::Builder::setResourceProvider(sk_sp<skresources::ResourceProvider> rp) {
    fResourceProvider = std::move(rp);
    return *this;
}

SkSVGDOM::Builder& SkSVGDOM::Builder::setTextShapingFactory(sk_sp<SkShapers::Factory> f) {
    fTextShapingFactory = f;
    return *this;
}

sk_sp<SkSVGDOM> SkSVGDOM::Builder::make(SkStream& str) const {
    TRACE_EVENT0("skia", TRACE_FUNC);
    SkDOM xmlDom;
    if (!xmlDom.build(str)) {
        return nullptr;
    }

    SkSVGIDMapper mapper;
    ConstructionContext ctx(&mapper);

    auto root = construct_svg_node(xmlDom, ctx, xmlDom.getRootNode());
    if (!root || root->tag() != SkSVGTag::kSvg) {
        return nullptr;
    }

    class NullResourceProvider final : public skresources::ResourceProvider {
        sk_sp<SkData> load(const char[], const char[]) const override { return nullptr; }
    };

    auto resource_provider = fResourceProvider ? fResourceProvider
                                               : sk_make_sp<NullResourceProvider>();

    auto factory = fTextShapingFactory ? fTextShapingFactory : SkShapers::Primitive::Factory();

    return sk_sp<SkSVGDOM>(new SkSVGDOM(sk_sp<SkSVGSVG>(static_cast<SkSVGSVG*>(root.release())),
                                        std::move(fFontMgr),
                                        std::move(resource_provider),
                                        std::move(mapper),
                                        std::move(factory)));
}

SkSVGDOM::SkSVGDOM(sk_sp<SkSVGSVG> root,
                   sk_sp<SkFontMgr> fmgr,
                   sk_sp<skresources::ResourceProvider> rp,
                   SkSVGIDMapper&& mapper,
                   sk_sp<SkShapers::Factory> fact)
        : fRoot(std::move(root))
        , fFontMgr(std::move(fmgr))
        , fTextShapingFactory(std::move(fact))
        , fResourceProvider(std::move(rp))
        , fIDMapper(std::move(mapper))
        , fContainerSize(fRoot->intrinsicSize(SkSVGLengthContext(SkSize::Make(0, 0)))) {
    SkASSERT(fResourceProvider);
    SkASSERT(fTextShapingFactory);
}

sk_sp<SkSVGDOM> SkSVGDOM::MakeFromStream(SkStream& str) { return Builder().make(str); }

void SkSVGDOM::render(SkCanvas* canvas) const {
    TRACE_EVENT0("skia", TRACE_FUNC);
    if (fRoot) {
        SkSVGLengthContext       lctx(fContainerSize);
        SkSVGPresentationContext pctx;
        fRoot->render(SkSVGRenderContext(canvas,
                                         fFontMgr,
                                         fResourceProvider,
                                         fIDMapper,
                                         lctx,
                                         pctx,
                                         {nullptr, nullptr},
                                         fTextShapingFactory));
    }
}

void SkSVGDOM::renderNode(SkCanvas* canvas, SkSVGPresentationContext& pctx, const char* id) const {
    TRACE_EVENT0("skia", TRACE_FUNC);

    if (fRoot) {
        SkSVGLengthContext lctx(fContainerSize);
        fRoot->renderNode(SkSVGRenderContext(canvas,
                                             fFontMgr,
                                             fResourceProvider,
                                             fIDMapper,
                                             lctx,
                                             pctx,
                                             {nullptr, nullptr},
                                             fTextShapingFactory),
                          SkSVGIRI(SkSVGIRI::Type::kLocal, SkSVGStringType(id)));
    }
}

const SkSize& SkSVGDOM::containerSize() const {
    return fContainerSize;
}

void SkSVGDOM::setContainerSize(const SkSize& containerSize) {
    // TODO: inval
    fContainerSize = containerSize;
}

sk_sp<SkSVGNode>* SkSVGDOM::findNodeById(const char* id) {
    SkString idStr(id);
    return this->fIDMapper.find(idStr);
}

// TODO(fuego): move this to SkSVGNode or its own CU.
bool SkSVGNode::setAttribute(const char* attributeName, const char* attributeValue) {
    return set_string_attribute(sk_ref_sp(this), attributeName, attributeValue);
}
