local p = {} -- Page object
local trackingCategories = {} -- Table for storing the tracking categories.
local demo

-- Define a custom error message for this module.
local function err
	local help
	if section then
		help = ' (도움말)'
	else
		help = ''
	end
	local cat
	if demo == 'yes' then
		cat = ''
	else
		cat = ''
	end
	return '' .. cat
end

-- To add more link types, write a function that produces an individual link, and put --
-- it at the bottom of the list below. Then, add a link code for your function to the --
-- "linktypes" table. Try and make the code three letters or less. 
--
-- If you want more helper strings, you can define them in the generatePageDataStrings --
-- function below. --

-- LINK FUNCTIONS START --

local function makePageLink
	return p.fullText and '' .. p.fullText .. '' or ''
end

local function makeTalkLink
	return '토론'
end

local function makeTalkOrSubjectLink
	if p.isTalkPage then
		return '주제'
	else
		return '토론'
	end
end

local function makeWhatLinksHereLink
	return '링크'
end

local function makeRelatedChangesLink
	return '관련 항목'
end

local function makeEditLink
	return '편집'
end

local function makeHistoryLink
	return '역사'
end

local function makeWatchLink
	return '[' .. p:fullUrl( 'action=watch' ) .. ' 주시]'
end

local function makeTargetLogsLink
	local url = mw.uri.fullUrl( '특수:기록', 'page=' .. mw.uri.encode(p.fullText) )
	return '[' .. tostring(url) .. ' 기록]'
end

local function makeEditFilterLogLink
	local url = mw.uri.fullUrl( '특수:AbuseLog', 'wpSearchTitle=' .. mw.uri.encode(p.fullText) )
	return '[' .. tostring(url) .. ' 편집&nbsp;필터&nbsp;기록]'
end

local function makePageViewsLink(args)
	local endDate, startDate = "", ""
	
	if args.date then
		local date = string.gsub
		date = os.time{year=string.sub, month=string.sub, day=string.sub}
		endDate = os.date("%Y-%m-%d", date - (1*86400))
		startDate = os.date("%Y-%m-%d", date - (30*86400))
	else
		endDate = os.date("%Y-%m-%d")
		startDate = os.date("%Y-%m-%d", os.time - (60*86400))
	end
	
	local project = string.sub
	local url = mw.uri.encode
	local urlargs = '?start=' .. startDate .. '&end=' .. endDate .. '&project=' .. project .. '&pages=' .. tostring(url)
	
	if #urlargs > 255 then -- Extra chars can tip it over the max length for an IW link.
		return '[https://pageviews.toolforge.org/?' .. urlargs .. ' 통계]'
	end
	return '통계'
end

local function makeHistory500Link
	local url = p:fullUrl( 'action=history&limit=500' );
	return '[' .. url .. ' 긴 역사]'
end

-- LINK FUNCTIONS END --
-- To enable new link functions, add the code to the "linktypes" table directly below. --

local linktypes = {
 ['t'] = makeTalkLink,
 ['ts'] = makeTalkOrSubjectLink,
 ['wlh'] = makeWhatLinksHereLink,
 ['rc'] = makeRelatedChangesLink,
 ['edit'] = makeEditLink,
 ['h'] = makeHistoryLink,
 ['w'] = makeWatchLink,
 ['tl'] = makeTargetLogsLink,
 ['efl'] = makeEditFilterLogLink,
 ['vlm-sgs'] = makePageViewsLink,
 ['pv'] = makePageViewsLink,
 ['h500'] = makeHistory500Link,

local function getLink
	local func = linktypes[linktype]
	if func then
		return func(args)
	else
 return err
	end
end

local function makeToolbar(args)
 local targs = {}
 local numArgsExist = false
 for k, v in pairs(args) do
 if type(k) == 'number' and p then
 numArgsExist = true
 targs[k] = getLink
 end
 end
 targs.style = args.small and 'font-size: 90%;'
 targs.separator = args.separator or 'dot'
 targs.class = 'lx'
 
 if numArgsExist == false then
 return nil -- Don't return a toolbar if no numeric arguments exist. -- this bit looks odd
 else
 return ToolbarBuilder.main(targs)
 end
end

local function generatePageDataStrings(args)
 -- If the page name is absent or blank, return an error and a tracking category.
 if args.page == '' or not args.page then
 return err('발견된 문서가 없습니다')
 end
 local noError
 noError, p = pcall
 if not noError then
 	return err('pcall mw.title 실패')
	end
	if args.exists and (not p or p['id'] == 0) then
 	return err('문서를 찾을 수 없습니다')
 end
end

local function generateTrackingCategories
 if demo == 'yes' then
 return ''
 else
 return table.concat(trackingCategories)
 end
end

-- This function generates a table of all available link types, with their previews.
-- It is used in the module documentation.
local function getLinkTable(args)
 demo = args.demo -- Set the demo variable.
 -- Generate the page data strings and return any errors.
 local dataStringError = generatePageDataStrings(args)
 if dataStringError then
 return dataStringError
 end
 
 -- Build a table of all of the links.
 local result = ''
 .. '\n'
 for i, value in ipairs(linktypes) do
 local code = value[1]
 result = result .. "\n'
 
 return result
end

local function getSingleLink(args)
 demo = args.demo -- Set the demo variable.
 -- Generate the page data strings and return any errors.
 local dataStringError = generatePageDataStrings(args)
 if dataStringError then
 return dataStringError
 end
 
 local linktype = args[1]
 if not linktype then 
 return err('지정된 링크 유형이 없습니다')
 end
 local result = getLink
 result = result .. generateTrackingCategories
 return result
end

local function getLinksToolbar(args)
 demo = args.demo -- Set the demo variable.
 -- Generate the page data strings and return any errors.
 local dataStringError = generatePageDataStrings(args)
 if dataStringError then
 return dataStringError
 end 
 
 -- Build the template output.
 local result = makeToolbar(args) -- Get the toolbar contents.
 result = (result or '') .. generateTrackingCategories
 return result
end

local function getLinks(args)
	local result = getLinksToolbar(args)

	if result then
		if args.sup then
			result = ''
		end
		result = '&nbsp;' .. result
	else
		result = '' -- If there are no links specified, don't return the toolbar at all.
	end
	if args.nopage then
		result = ''
	else
		if p then
			result = ''
		else
			result = ''
		end
	end

	return result
end

local function getExampleLinks(args)
 -- This function enables example output without having to specify any
 -- parameters to #invoke.
 args.demo = 'yes'
 args.page = 'Example'
 return getLinks(args)
end

local function makeWrapper(func)
 return function (frame)
 -- If called via #invoke, use the args passed into the invoking template.
 -- Otherwise, for testing purposes, assume args are being passed directly in.
 local origArgs
 if frame == mw.getCurrentFrame then
 origArgs = frame:getParent.args
 for k, v in pairs(frame.args) do
 origArgs = frame.args
 break
 end
 else
 origArgs = frame
 end
 
 -- Strip whitespace, and treat blank arguments as nil.
 -- 'page', and 'separator' have different behaviour depending on
 -- whether they are blank or nil, so keep them as they are.
 local args = {}
 for k, v in pairs(origArgs) do
 v = mw.text.trim(v)
 if v ~= '' or k == 'page' or k == 'separator' then
 args[k] = v
 end
 end
 
 return func(args)
 end
end

return {
 main = makeWrapper(getLinks),
 single = makeWrapper(getSingleLink),
 toolbar = makeWrapper(getLinksToolbar),
 linktable = makeWrapper(getLinkTable),
 example = makeWrapper(getExampleLinks)